vfp.hh (7430:db3e376f35d1) vfp.hh (7639:8c09b7ff5b57)
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Gabe Black
38 */
39
40#ifndef __ARCH_ARM_INSTS_VFP_HH__
41#define __ARCH_ARM_INSTS_VFP_HH__
42
43#include "arch/arm/insts/misc.hh"
44#include "arch/arm/miscregs.hh"
45#include <fenv.h>
46#include <cmath>
47
48namespace ArmISA
49{
50
51enum VfpMicroMode {
52 VfpNotAMicroop,
53 VfpMicroop,
54 VfpFirstMicroop,
55 VfpLastMicroop
56};
57
58template<class T>
59static inline void
60setVfpMicroFlags(VfpMicroMode mode, T &flags)
61{
62 switch (mode) {
63 case VfpMicroop:
64 flags[StaticInst::IsMicroop] = true;
65 break;
66 case VfpFirstMicroop:
67 flags[StaticInst::IsMicroop] =
68 flags[StaticInst::IsFirstMicroop] = true;
69 break;
70 case VfpLastMicroop:
71 flags[StaticInst::IsMicroop] =
72 flags[StaticInst::IsLastMicroop] = true;
73 break;
74 case VfpNotAMicroop:
75 break;
76 }
77 if (mode == VfpMicroop || mode == VfpFirstMicroop) {
78 flags[StaticInst::IsDelayedCommit] = true;
79 }
80}
81
82enum FeExceptionBit
83{
84 FeDivByZero = FE_DIVBYZERO,
85 FeInexact = FE_INEXACT,
86 FeInvalid = FE_INVALID,
87 FeOverflow = FE_OVERFLOW,
88 FeUnderflow = FE_UNDERFLOW,
89 FeAllExceptions = FE_ALL_EXCEPT
90};
91
92enum FeRoundingMode
93{
94 FeRoundDown = FE_DOWNWARD,
95 FeRoundNearest = FE_TONEAREST,
96 FeRoundZero = FE_TOWARDZERO,
97 FeRoundUpward = FE_UPWARD
98};
99
100enum VfpRoundingMode
101{
102 VfpRoundNearest = 0,
103 VfpRoundUpward = 1,
104 VfpRoundDown = 2,
105 VfpRoundZero = 3
106};
107
108template <class fpType>
109static inline bool
110flushToZero(fpType &op)
111{
112 fpType junk = 0.0;
113 if (std::fpclassify(op) == FP_SUBNORMAL) {
114 uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1);
115 op = bitsToFp(fpToBits(op) & bitMask, junk);
116 return true;
117 }
118 return false;
119}
120
121template <class fpType>
122static inline bool
123flushToZero(fpType &op1, fpType &op2)
124{
125 bool flush1 = flushToZero(op1);
126 bool flush2 = flushToZero(op2);
127 return flush1 || flush2;
128}
129
130template <class fpType>
131static inline void
132vfpFlushToZero(FPSCR &fpscr, fpType &op)
133{
134 if (fpscr.fz == 1 && flushToZero(op)) {
135 fpscr.idc = 1;
136 }
137}
138
139template <class fpType>
140static inline void
141vfpFlushToZero(FPSCR &fpscr, fpType &op1, fpType &op2)
142{
143 vfpFlushToZero(fpscr, op1);
144 vfpFlushToZero(fpscr, op2);
145}
146
147static inline uint32_t
148fpToBits(float fp)
149{
150 union
151 {
152 float fp;
153 uint32_t bits;
154 } val;
155 val.fp = fp;
156 return val.bits;
157}
158
159static inline uint64_t
160fpToBits(double fp)
161{
162 union
163 {
164 double fp;
165 uint64_t bits;
166 } val;
167 val.fp = fp;
168 return val.bits;
169}
170
171static inline float
172bitsToFp(uint64_t bits, float junk)
173{
174 union
175 {
176 float fp;
177 uint32_t bits;
178 } val;
179 val.bits = bits;
180 return val.fp;
181}
182
183static inline double
184bitsToFp(uint64_t bits, double junk)
185{
186 union
187 {
188 double fp;
189 uint64_t bits;
190 } val;
191 val.bits = bits;
192 return val.fp;
193}
194
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Gabe Black
38 */
39
40#ifndef __ARCH_ARM_INSTS_VFP_HH__
41#define __ARCH_ARM_INSTS_VFP_HH__
42
43#include "arch/arm/insts/misc.hh"
44#include "arch/arm/miscregs.hh"
45#include <fenv.h>
46#include <cmath>
47
48namespace ArmISA
49{
50
51enum VfpMicroMode {
52 VfpNotAMicroop,
53 VfpMicroop,
54 VfpFirstMicroop,
55 VfpLastMicroop
56};
57
58template<class T>
59static inline void
60setVfpMicroFlags(VfpMicroMode mode, T &flags)
61{
62 switch (mode) {
63 case VfpMicroop:
64 flags[StaticInst::IsMicroop] = true;
65 break;
66 case VfpFirstMicroop:
67 flags[StaticInst::IsMicroop] =
68 flags[StaticInst::IsFirstMicroop] = true;
69 break;
70 case VfpLastMicroop:
71 flags[StaticInst::IsMicroop] =
72 flags[StaticInst::IsLastMicroop] = true;
73 break;
74 case VfpNotAMicroop:
75 break;
76 }
77 if (mode == VfpMicroop || mode == VfpFirstMicroop) {
78 flags[StaticInst::IsDelayedCommit] = true;
79 }
80}
81
82enum FeExceptionBit
83{
84 FeDivByZero = FE_DIVBYZERO,
85 FeInexact = FE_INEXACT,
86 FeInvalid = FE_INVALID,
87 FeOverflow = FE_OVERFLOW,
88 FeUnderflow = FE_UNDERFLOW,
89 FeAllExceptions = FE_ALL_EXCEPT
90};
91
92enum FeRoundingMode
93{
94 FeRoundDown = FE_DOWNWARD,
95 FeRoundNearest = FE_TONEAREST,
96 FeRoundZero = FE_TOWARDZERO,
97 FeRoundUpward = FE_UPWARD
98};
99
100enum VfpRoundingMode
101{
102 VfpRoundNearest = 0,
103 VfpRoundUpward = 1,
104 VfpRoundDown = 2,
105 VfpRoundZero = 3
106};
107
108template <class fpType>
109static inline bool
110flushToZero(fpType &op)
111{
112 fpType junk = 0.0;
113 if (std::fpclassify(op) == FP_SUBNORMAL) {
114 uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1);
115 op = bitsToFp(fpToBits(op) & bitMask, junk);
116 return true;
117 }
118 return false;
119}
120
121template <class fpType>
122static inline bool
123flushToZero(fpType &op1, fpType &op2)
124{
125 bool flush1 = flushToZero(op1);
126 bool flush2 = flushToZero(op2);
127 return flush1 || flush2;
128}
129
130template <class fpType>
131static inline void
132vfpFlushToZero(FPSCR &fpscr, fpType &op)
133{
134 if (fpscr.fz == 1 && flushToZero(op)) {
135 fpscr.idc = 1;
136 }
137}
138
139template <class fpType>
140static inline void
141vfpFlushToZero(FPSCR &fpscr, fpType &op1, fpType &op2)
142{
143 vfpFlushToZero(fpscr, op1);
144 vfpFlushToZero(fpscr, op2);
145}
146
147static inline uint32_t
148fpToBits(float fp)
149{
150 union
151 {
152 float fp;
153 uint32_t bits;
154 } val;
155 val.fp = fp;
156 return val.bits;
157}
158
159static inline uint64_t
160fpToBits(double fp)
161{
162 union
163 {
164 double fp;
165 uint64_t bits;
166 } val;
167 val.fp = fp;
168 return val.bits;
169}
170
171static inline float
172bitsToFp(uint64_t bits, float junk)
173{
174 union
175 {
176 float fp;
177 uint32_t bits;
178 } val;
179 val.bits = bits;
180 return val.fp;
181}
182
183static inline double
184bitsToFp(uint64_t bits, double junk)
185{
186 union
187 {
188 double fp;
189 uint64_t bits;
190 } val;
191 val.bits = bits;
192 return val.fp;
193}
194
195template <class fpType>
196static bool
197isSnan(fpType val)
198{
199 const bool single = (sizeof(fpType) == sizeof(float));
200 const uint64_t qnan =
201 single ? 0x7fc00000 : ULL(0x7ff8000000000000);
202 return std::isnan(val) && ((fpToBits(val) & qnan) != qnan);
203}
204
195typedef int VfpSavedState;
196
197VfpSavedState prepFpState(uint32_t rMode);
205typedef int VfpSavedState;
206
207VfpSavedState prepFpState(uint32_t rMode);
198void finishVfp(FPSCR &fpscr, VfpSavedState state);
208void finishVfp(FPSCR &fpscr, VfpSavedState state, bool flush);
199
200template <class fpType>
201fpType fixDest(FPSCR fpscr, fpType val, fpType op1);
202
203template <class fpType>
204fpType fixDest(FPSCR fpscr, fpType val, fpType op1, fpType op2);
205
206template <class fpType>
207fpType fixDivDest(FPSCR fpscr, fpType val, fpType op1, fpType op2);
208
209float fixFpDFpSDest(FPSCR fpscr, double val);
210double fixFpSFpDDest(FPSCR fpscr, float val);
211
209
210template <class fpType>
211fpType fixDest(FPSCR fpscr, fpType val, fpType op1);
212
213template <class fpType>
214fpType fixDest(FPSCR fpscr, fpType val, fpType op1, fpType op2);
215
216template <class fpType>
217fpType fixDivDest(FPSCR fpscr, fpType val, fpType op1, fpType op2);
218
219float fixFpDFpSDest(FPSCR fpscr, double val);
220double fixFpSFpDDest(FPSCR fpscr, float val);
221
212float vcvtFpSFpH(FPSCR &fpscr, float op, float dest, bool top);
213float vcvtFpHFpS(FPSCR &fpscr, float op, bool top);
222uint16_t vcvtFpSFpH(FPSCR &fpscr, bool flush, bool defaultNan,
223 uint32_t rMode, bool ahp, float op);
224float vcvtFpHFpS(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op);
214
215static inline double
216makeDouble(uint32_t low, uint32_t high)
217{
218 double junk = 0.0;
219 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
220}
221
222static inline uint32_t
223lowFromDouble(double val)
224{
225 return fpToBits(val);
226}
227
228static inline uint32_t
229highFromDouble(double val)
230{
231 return fpToBits(val) >> 32;
232}
233
234uint64_t vfpFpSToFixed(float val, bool isSigned, bool half,
235 uint8_t imm, bool rzero = true);
225
226static inline double
227makeDouble(uint32_t low, uint32_t high)
228{
229 double junk = 0.0;
230 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
231}
232
233static inline uint32_t
234lowFromDouble(double val)
235{
236 return fpToBits(val);
237}
238
239static inline uint32_t
240highFromDouble(double val)
241{
242 return fpToBits(val) >> 32;
243}
244
245uint64_t vfpFpSToFixed(float val, bool isSigned, bool half,
246 uint8_t imm, bool rzero = true);
236float vfpUFixedToFpS(FPSCR fpscr, uint32_t val, bool half, uint8_t imm);
237float vfpSFixedToFpS(FPSCR fpscr, int32_t val, bool half, uint8_t imm);
247float vfpUFixedToFpS(bool flush, bool defaultNan,
248 uint32_t val, bool half, uint8_t imm);
249float vfpSFixedToFpS(bool flush, bool defaultNan,
250 int32_t val, bool half, uint8_t imm);
238
239uint64_t vfpFpDToFixed(double val, bool isSigned, bool half,
240 uint8_t imm, bool rzero = true);
251
252uint64_t vfpFpDToFixed(double val, bool isSigned, bool half,
253 uint8_t imm, bool rzero = true);
241double vfpUFixedToFpD(FPSCR fpscr, uint32_t val, bool half, uint8_t imm);
242double vfpSFixedToFpD(FPSCR fpscr, int32_t val, bool half, uint8_t imm);
254double vfpUFixedToFpD(bool flush, bool defaultNan,
255 uint32_t val, bool half, uint8_t imm);
256double vfpSFixedToFpD(bool flush, bool defaultNan,
257 int32_t val, bool half, uint8_t imm);
243
258
259float fprSqrtEstimate(FPSCR &fpscr, float op);
260uint32_t unsignedRSqrtEstimate(uint32_t op);
261
262float fpRecipEstimate(FPSCR &fpscr, float op);
263uint32_t unsignedRecipEstimate(uint32_t op);
264
244class VfpMacroOp : public PredMacroOp
245{
246 public:
247 static bool
248 inScalarBank(IntRegIndex idx)
249 {
250 return (idx % 32) < 8;
251 }
252
253 protected:
254 bool wide;
255
256 VfpMacroOp(const char *mnem, ExtMachInst _machInst,
257 OpClass __opClass, bool _wide) :
258 PredMacroOp(mnem, _machInst, __opClass), wide(_wide)
259 {}
260
261 IntRegIndex addStride(IntRegIndex idx, unsigned stride);
262 void nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2);
263 void nextIdxs(IntRegIndex &dest, IntRegIndex &op1);
264 void nextIdxs(IntRegIndex &dest);
265};
266
267static inline float
268fpAddS(float a, float b)
269{
270 return a + b;
271}
272
273static inline double
274fpAddD(double a, double b)
275{
276 return a + b;
277}
278
279static inline float
280fpSubS(float a, float b)
281{
282 return a - b;
283}
284
285static inline double
286fpSubD(double a, double b)
287{
288 return a - b;
289}
290
291static inline float
292fpDivS(float a, float b)
293{
294 return a / b;
295}
296
297static inline double
298fpDivD(double a, double b)
299{
300 return a / b;
301}
302
303static inline float
304fpMulS(float a, float b)
305{
306 return a * b;
307}
308
309static inline double
310fpMulD(double a, double b)
311{
312 return a * b;
313}
314
265class VfpMacroOp : public PredMacroOp
266{
267 public:
268 static bool
269 inScalarBank(IntRegIndex idx)
270 {
271 return (idx % 32) < 8;
272 }
273
274 protected:
275 bool wide;
276
277 VfpMacroOp(const char *mnem, ExtMachInst _machInst,
278 OpClass __opClass, bool _wide) :
279 PredMacroOp(mnem, _machInst, __opClass), wide(_wide)
280 {}
281
282 IntRegIndex addStride(IntRegIndex idx, unsigned stride);
283 void nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2);
284 void nextIdxs(IntRegIndex &dest, IntRegIndex &op1);
285 void nextIdxs(IntRegIndex &dest);
286};
287
288static inline float
289fpAddS(float a, float b)
290{
291 return a + b;
292}
293
294static inline double
295fpAddD(double a, double b)
296{
297 return a + b;
298}
299
300static inline float
301fpSubS(float a, float b)
302{
303 return a - b;
304}
305
306static inline double
307fpSubD(double a, double b)
308{
309 return a - b;
310}
311
312static inline float
313fpDivS(float a, float b)
314{
315 return a / b;
316}
317
318static inline double
319fpDivD(double a, double b)
320{
321 return a / b;
322}
323
324static inline float
325fpMulS(float a, float b)
326{
327 return a * b;
328}
329
330static inline double
331fpMulD(double a, double b)
332{
333 return a * b;
334}
335
336static inline float
337fpMaxS(float a, float b)
338{
339 // Handle comparisons of +0 and -0.
340 if (!std::signbit(a) && std::signbit(b))
341 return a;
342 return fmaxf(a, b);
343}
344
345static inline float
346fpMinS(float a, float b)
347{
348 // Handle comparisons of +0 and -0.
349 if (std::signbit(a) && !std::signbit(b))
350 return a;
351 return fminf(a, b);
352}
353
354static inline float
355fpRSqrtsS(float a, float b)
356{
357 int fpClassA = std::fpclassify(a);
358 int fpClassB = std::fpclassify(b);
359 float aXb;
360 int fpClassAxB;
361
362 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
363 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
364 return 1.5;
365 }
366 aXb = a*b;
367 fpClassAxB = std::fpclassify(aXb);
368 if(fpClassAxB == FP_SUBNORMAL) {
369 feraiseexcept(FeUnderflow);
370 return 1.5;
371 }
372 return (3.0 - (a * b)) / 2.0;
373}
374
375static inline float
376fpRecpsS(float a, float b)
377{
378 int fpClassA = std::fpclassify(a);
379 int fpClassB = std::fpclassify(b);
380 float aXb;
381 int fpClassAxB;
382
383 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
384 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
385 return 2.0;
386 }
387 aXb = a*b;
388 fpClassAxB = std::fpclassify(aXb);
389 if(fpClassAxB == FP_SUBNORMAL) {
390 feraiseexcept(FeUnderflow);
391 return 2.0;
392 }
393 return 2.0 - (a * b);
394}
395
315class FpOp : public PredOp
316{
317 protected:
318 FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
319 PredOp(mnem, _machInst, __opClass)
320 {}
321
322 virtual float
323 doOp(float op1, float op2) const
324 {
325 panic("Unimplemented version of doOp called.\n");
326 }
327
328 virtual float
329 doOp(float op1) const
330 {
331 panic("Unimplemented version of doOp called.\n");
332 }
333
334 virtual double
335 doOp(double op1, double op2) const
336 {
337 panic("Unimplemented version of doOp called.\n");
338 }
339
340 virtual double
341 doOp(double op1) const
342 {
343 panic("Unimplemented version of doOp called.\n");
344 }
345
346 double
347 dbl(uint32_t low, uint32_t high) const
348 {
349 double junk = 0.0;
350 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
351 }
352
353 uint32_t
354 dblLow(double val) const
355 {
356 return fpToBits(val);
357 }
358
359 uint32_t
360 dblHi(double val) const
361 {
362 return fpToBits(val) >> 32;
363 }
364
365 template <class fpType>
366 fpType
396class FpOp : public PredOp
397{
398 protected:
399 FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
400 PredOp(mnem, _machInst, __opClass)
401 {}
402
403 virtual float
404 doOp(float op1, float op2) const
405 {
406 panic("Unimplemented version of doOp called.\n");
407 }
408
409 virtual float
410 doOp(float op1) const
411 {
412 panic("Unimplemented version of doOp called.\n");
413 }
414
415 virtual double
416 doOp(double op1, double op2) const
417 {
418 panic("Unimplemented version of doOp called.\n");
419 }
420
421 virtual double
422 doOp(double op1) const
423 {
424 panic("Unimplemented version of doOp called.\n");
425 }
426
427 double
428 dbl(uint32_t low, uint32_t high) const
429 {
430 double junk = 0.0;
431 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
432 }
433
434 uint32_t
435 dblLow(double val) const
436 {
437 return fpToBits(val);
438 }
439
440 uint32_t
441 dblHi(double val) const
442 {
443 return fpToBits(val) >> 32;
444 }
445
446 template <class fpType>
447 fpType
448 processNans(FPSCR &fpscr, bool &done, bool defaultNan,
449 fpType op1, fpType op2) const;
450
451 template <class fpType>
452 fpType
367 binaryOp(FPSCR &fpscr, fpType op1, fpType op2,
368 fpType (*func)(fpType, fpType),
453 binaryOp(FPSCR &fpscr, fpType op1, fpType op2,
454 fpType (*func)(fpType, fpType),
369 bool flush, uint32_t rMode) const;
455 bool flush, bool defaultNan, uint32_t rMode) const;
370
371 template <class fpType>
372 fpType
373 unaryOp(FPSCR &fpscr, fpType op1,
374 fpType (*func)(fpType),
375 bool flush, uint32_t rMode) const;
376};
377
378class FpRegRegOp : public FpOp
379{
380 protected:
381 IntRegIndex dest;
382 IntRegIndex op1;
383
384 FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
385 IntRegIndex _dest, IntRegIndex _op1,
386 VfpMicroMode mode = VfpNotAMicroop) :
387 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1)
388 {
389 setVfpMicroFlags(mode, flags);
390 }
391
392 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
393};
394
395class FpRegImmOp : public FpOp
396{
397 protected:
398 IntRegIndex dest;
399 uint64_t imm;
400
401 FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
402 IntRegIndex _dest, uint64_t _imm,
403 VfpMicroMode mode = VfpNotAMicroop) :
404 FpOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm)
405 {
406 setVfpMicroFlags(mode, flags);
407 }
408
409 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
410};
411
412class FpRegRegImmOp : public FpOp
413{
414 protected:
415 IntRegIndex dest;
416 IntRegIndex op1;
417 uint64_t imm;
418
419 FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
420 IntRegIndex _dest, IntRegIndex _op1,
421 uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) :
422 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm)
423 {
424 setVfpMicroFlags(mode, flags);
425 }
426
427 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
428};
429
430class FpRegRegRegOp : public FpOp
431{
432 protected:
433 IntRegIndex dest;
434 IntRegIndex op1;
435 IntRegIndex op2;
436
437 FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
438 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
439 VfpMicroMode mode = VfpNotAMicroop) :
440 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2)
441 {
442 setVfpMicroFlags(mode, flags);
443 }
444
445 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
446};
447
456
457 template <class fpType>
458 fpType
459 unaryOp(FPSCR &fpscr, fpType op1,
460 fpType (*func)(fpType),
461 bool flush, uint32_t rMode) const;
462};
463
464class FpRegRegOp : public FpOp
465{
466 protected:
467 IntRegIndex dest;
468 IntRegIndex op1;
469
470 FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
471 IntRegIndex _dest, IntRegIndex _op1,
472 VfpMicroMode mode = VfpNotAMicroop) :
473 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1)
474 {
475 setVfpMicroFlags(mode, flags);
476 }
477
478 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
479};
480
481class FpRegImmOp : public FpOp
482{
483 protected:
484 IntRegIndex dest;
485 uint64_t imm;
486
487 FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
488 IntRegIndex _dest, uint64_t _imm,
489 VfpMicroMode mode = VfpNotAMicroop) :
490 FpOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm)
491 {
492 setVfpMicroFlags(mode, flags);
493 }
494
495 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
496};
497
498class FpRegRegImmOp : public FpOp
499{
500 protected:
501 IntRegIndex dest;
502 IntRegIndex op1;
503 uint64_t imm;
504
505 FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
506 IntRegIndex _dest, IntRegIndex _op1,
507 uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) :
508 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm)
509 {
510 setVfpMicroFlags(mode, flags);
511 }
512
513 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
514};
515
516class FpRegRegRegOp : public FpOp
517{
518 protected:
519 IntRegIndex dest;
520 IntRegIndex op1;
521 IntRegIndex op2;
522
523 FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
524 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
525 VfpMicroMode mode = VfpNotAMicroop) :
526 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2)
527 {
528 setVfpMicroFlags(mode, flags);
529 }
530
531 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
532};
533
534class FpRegRegRegImmOp : public FpOp
535{
536 protected:
537 IntRegIndex dest;
538 IntRegIndex op1;
539 IntRegIndex op2;
540 uint64_t imm;
541
542 FpRegRegRegImmOp(const char *mnem, ExtMachInst _machInst,
543 OpClass __opClass, IntRegIndex _dest,
544 IntRegIndex _op1, IntRegIndex _op2,
545 uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) :
546 FpOp(mnem, _machInst, __opClass),
547 dest(_dest), op1(_op1), op2(_op2), imm(_imm)
548 {
549 setVfpMicroFlags(mode, flags);
550 }
551
552 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
553};
554
448}
449
450#endif //__ARCH_ARM_INSTS_VFP_HH__
555}
556
557#endif //__ARCH_ARM_INSTS_VFP_HH__