gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
vfp.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2013, 2019 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 <fenv.h>
44 
45 #include <cmath>
46 
47 #include "arch/arm/insts/misc.hh"
48 #include "arch/arm/miscregs.hh"
49 
50 namespace ArmISA
51 {
52 
58 };
59 
60 template<class T>
61 static inline void
63 {
64  switch (mode) {
65  case VfpMicroop:
66  flags[StaticInst::IsMicroop] = true;
67  break;
68  case VfpFirstMicroop:
69  flags[StaticInst::IsMicroop] =
70  flags[StaticInst::IsFirstMicroop] = true;
71  break;
72  case VfpLastMicroop:
73  flags[StaticInst::IsMicroop] =
74  flags[StaticInst::IsLastMicroop] = true;
75  break;
76  case VfpNotAMicroop:
77  break;
78  }
79  if (mode == VfpMicroop || mode == VfpFirstMicroop) {
80  flags[StaticInst::IsDelayedCommit] = true;
81  }
82 }
83 
85 {
86  FeDivByZero = FE_DIVBYZERO,
87  FeInexact = FE_INEXACT,
88  FeInvalid = FE_INVALID,
89  FeOverflow = FE_OVERFLOW,
90  FeUnderflow = FE_UNDERFLOW,
91  FeAllExceptions = FE_ALL_EXCEPT
92 };
93 
95 {
96  FeRoundDown = FE_DOWNWARD,
97  FeRoundNearest = FE_TONEAREST,
98  FeRoundZero = FE_TOWARDZERO,
99  FeRoundUpward = FE_UPWARD
100 };
101 
103 {
109 };
110 
111 static inline float bitsToFp(uint64_t, float);
112 static inline double bitsToFp(uint64_t, double);
113 static inline uint32_t fpToBits(float);
114 static inline uint64_t fpToBits(double);
115 
116 template <class fpType>
117 static inline bool
118 flushToZero(fpType &op)
119 {
120  fpType junk = 0.0;
121  if (std::fpclassify(op) == FP_SUBNORMAL) {
122  uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1);
123  op = bitsToFp(fpToBits(op) & bitMask, junk);
124  return true;
125  }
126  return false;
127 }
128 
129 template <class fpType>
130 static inline bool
131 flushToZero(fpType &op1, fpType &op2)
132 {
133  bool flush1 = flushToZero(op1);
134  bool flush2 = flushToZero(op2);
135  return flush1 || flush2;
136 }
137 
138 template <class fpType>
139 static inline void
140 vfpFlushToZero(FPSCR &fpscr, fpType &op)
141 {
142  if (fpscr.fz == 1 && flushToZero(op)) {
143  fpscr.idc = 1;
144  }
145 }
146 
147 template <class fpType>
148 static inline void
149 vfpFlushToZero(FPSCR &fpscr, fpType &op1, fpType &op2)
150 {
151  vfpFlushToZero(fpscr, op1);
152  vfpFlushToZero(fpscr, op2);
153 }
154 
155 static inline uint32_t
156 fpToBits(float fp)
157 {
158  union
159  {
160  float fp;
161  uint32_t bits;
162  } val;
163  val.fp = fp;
164  return val.bits;
165 }
166 
167 static inline uint64_t
168 fpToBits(double fp)
169 {
170  union
171  {
172  double fp;
173  uint64_t bits;
174  } val;
175  val.fp = fp;
176  return val.bits;
177 }
178 
179 static inline float
180 bitsToFp(uint64_t bits, float junk)
181 {
182  union
183  {
184  float fp;
185  uint32_t bits;
186  } val;
187  val.bits = bits;
188  return val.fp;
189 }
190 
191 static inline double
192 bitsToFp(uint64_t bits, double junk)
193 {
194  union
195  {
196  double fp;
197  uint64_t bits;
198  } val;
199  val.bits = bits;
200  return val.fp;
201 }
202 
203 template <class fpType>
204 static inline bool
205 isSnan(fpType val)
206 {
207  const bool single = (sizeof(fpType) == sizeof(float));
208  const uint64_t qnan =
209  single ? 0x7fc00000 : ULL(0x7ff8000000000000);
210  return std::isnan(val) && ((fpToBits(val) & qnan) != qnan);
211 }
212 
213 typedef int VfpSavedState;
214 
215 VfpSavedState prepFpState(uint32_t rMode);
216 void finishVfp(FPSCR &fpscr, VfpSavedState state, bool flush, FPSCR mask = FpscrExcMask);
217 
218 template <class fpType>
219 fpType fixDest(FPSCR fpscr, fpType val, fpType op1);
220 
221 template <class fpType>
222 fpType fixDest(FPSCR fpscr, fpType val, fpType op1, fpType op2);
223 
224 template <class fpType>
225 fpType fixDivDest(FPSCR fpscr, fpType val, fpType op1, fpType op2);
226 
227 float fixFpDFpSDest(FPSCR fpscr, double val);
228 double fixFpSFpDDest(FPSCR fpscr, float val);
229 
230 uint16_t vcvtFpSFpH(FPSCR &fpscr, bool flush, bool defaultNan,
231  uint32_t rMode, bool ahp, float op);
232 uint16_t vcvtFpDFpH(FPSCR &fpscr, bool flush, bool defaultNan,
233  uint32_t rMode, bool ahp, double op);
234 
235 float vcvtFpHFpS(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op);
236 double vcvtFpHFpD(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op);
237 
238 static inline double
239 makeDouble(uint32_t low, uint32_t high)
240 {
241  double junk = 0.0;
242  return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
243 }
244 
245 static inline uint32_t
247 {
248  return fpToBits(val);
249 }
250 
251 static inline uint32_t
253 {
254  return fpToBits(val) >> 32;
255 }
256 
257 static inline void
258 setFPExceptions(int exceptions) {
259  feclearexcept(FeAllExceptions);
260  feraiseexcept(exceptions);
261 }
262 
263 template <typename T>
264 uint64_t
265 vfpFpToFixed(T val, bool isSigned, uint8_t width, uint8_t imm, bool
266  useRmode = true, VfpRoundingMode roundMode = VfpRoundZero,
267  bool aarch64 = false)
268 {
269  int rmode;
270  bool roundAwayFix = false;
271 
272  if (!useRmode) {
273  rmode = fegetround();
274  } else {
275  switch (roundMode)
276  {
277  case VfpRoundNearest:
278  rmode = FeRoundNearest;
279  break;
280  case VfpRoundUpward:
281  rmode = FeRoundUpward;
282  break;
283  case VfpRoundDown:
284  rmode = FeRoundDown;
285  break;
286  case VfpRoundZero:
287  rmode = FeRoundZero;
288  break;
289  case VfpRoundAway:
290  // There is no equivalent rounding mode, use round down and we'll
291  // fix it later
292  rmode = FeRoundDown;
293  roundAwayFix = true;
294  break;
295  default:
296  panic("Unsupported roundMode %d\n", roundMode);
297  }
298  }
299  __asm__ __volatile__("" : "=m" (rmode) : "m" (rmode));
300  fesetround(FeRoundNearest);
301  val = val * pow(2.0, imm);
302  __asm__ __volatile__("" : "=m" (val) : "m" (val));
303  fesetround(rmode);
304  feclearexcept(FeAllExceptions);
305  __asm__ __volatile__("" : "=m" (val) : "m" (val));
306  T origVal = val;
307  val = rint(val);
308  __asm__ __volatile__("" : "=m" (val) : "m" (val));
309 
310  int exceptions = fetestexcept(FeAllExceptions);
311 
312  int fpType = std::fpclassify(val);
313  if (fpType == FP_SUBNORMAL || fpType == FP_NAN) {
314  if (fpType == FP_NAN) {
315  exceptions |= FeInvalid;
316  }
317  val = 0.0;
318  } else if (origVal != val) {
319  switch (rmode) {
320  case FeRoundNearest:
321  if (origVal - val > 0.5)
322  val += 1.0;
323  else if (val - origVal > 0.5)
324  val -= 1.0;
325  break;
326  case FeRoundDown:
327  if (roundAwayFix) {
328  // The ordering on the subtraction looks a bit odd in that we
329  // don't do the obvious origVal - val, instead we do
330  // -(val - origVal). This is required to get the corruct bit
331  // exact behaviour when very close to the 0.5 threshold.
332  volatile T error = val;
333  error -= origVal;
334  error = -error;
335  if ( (error > 0.5) ||
336  ((error == 0.5) && (val >= 0)) )
337  val += 1.0;
338  } else {
339  if (origVal < val)
340  val -= 1.0;
341  }
342  break;
343  case FeRoundUpward:
344  if (origVal > val)
345  val += 1.0;
346  break;
347  }
348  exceptions |= FeInexact;
349  }
350 
351  __asm__ __volatile__("" : "=m" (val) : "m" (val));
352 
353  if (isSigned) {
354  bool outOfRange = false;
355  int64_t result = (int64_t) val;
356  uint64_t finalVal;
357 
358  if (!aarch64) {
359  if (width == 16) {
360  finalVal = (int16_t)val;
361  } else if (width == 32) {
362  finalVal =(int32_t)val;
363  } else if (width == 64) {
364  finalVal = result;
365  } else {
366  panic("Unsupported width %d\n", width);
367  }
368 
369  // check if value is in range
370  int64_t minVal = ~mask(width-1);
371  if ((double)val < minVal) {
372  outOfRange = true;
373  finalVal = minVal;
374  }
375  int64_t maxVal = mask(width-1);
376  if ((double)val > maxVal) {
377  outOfRange = true;
378  finalVal = maxVal;
379  }
380  } else {
381  bool isNeg = val < 0;
382  finalVal = result & mask(width);
383  // If the result is supposed to be less than 64 bits check that the
384  // upper bits that got thrown away are just sign extension bits
385  if (width != 64) {
386  outOfRange = ((uint64_t) result >> (width - 1)) !=
387  (isNeg ? mask(64-width+1) : 0);
388  }
389  // Check if the original floating point value doesn't matches the
390  // integer version we are also out of range. So create a saturated
391  // result.
392  if (isNeg) {
393  outOfRange |= val < result;
394  if (outOfRange) {
395  finalVal = 1LL << (width-1);
396  }
397  } else {
398  outOfRange |= val > result;
399  if (outOfRange) {
400  finalVal = mask(width-1);
401  }
402  }
403  }
404 
405  // Raise an exception if the value was out of range
406  if (outOfRange) {
407  exceptions |= FeInvalid;
408  exceptions &= ~FeInexact;
409  }
410  setFPExceptions(exceptions);
411  return finalVal;
412  } else {
413  if ((double)val < 0) {
414  exceptions |= FeInvalid;
415  exceptions &= ~FeInexact;
416  setFPExceptions(exceptions);
417  return 0;
418  }
419 
420  uint64_t result = ((uint64_t) val) & mask(width);
421  if (val > result) {
422  exceptions |= FeInvalid;
423  exceptions &= ~FeInexact;
424  setFPExceptions(exceptions);
425  return mask(width);
426  }
427 
428  setFPExceptions(exceptions);
429  return result;
430  }
431 };
432 
433 
434 float vfpUFixedToFpS(bool flush, bool defaultNan,
435  uint64_t val, uint8_t width, uint8_t imm);
436 float vfpSFixedToFpS(bool flush, bool defaultNan,
437  int64_t val, uint8_t width, uint8_t imm);
438 
439 double vfpUFixedToFpD(bool flush, bool defaultNan,
440  uint64_t val, uint8_t width, uint8_t imm);
441 double vfpSFixedToFpD(bool flush, bool defaultNan,
442  int64_t val, uint8_t width, uint8_t imm);
443 
444 float fprSqrtEstimate(FPSCR &fpscr, float op);
445 uint32_t unsignedRSqrtEstimate(uint32_t op);
446 
447 float fpRecipEstimate(FPSCR &fpscr, float op);
448 uint32_t unsignedRecipEstimate(uint32_t op);
449 
450 FPSCR
451 fpStandardFPSCRValue(const FPSCR &fpscr);
452 
453 class VfpMacroOp : public PredMacroOp
454 {
455  public:
456  static bool
458  {
459  return (idx % 32) < 8;
460  }
461 
462  protected:
463  bool wide;
464 
465  VfpMacroOp(const char *mnem, ExtMachInst _machInst,
466  OpClass __opClass, bool _wide) :
467  PredMacroOp(mnem, _machInst, __opClass), wide(_wide)
468  {}
469 
470  IntRegIndex addStride(IntRegIndex idx, unsigned stride);
471  void nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2);
472  void nextIdxs(IntRegIndex &dest, IntRegIndex &op1);
473  void nextIdxs(IntRegIndex &dest);
474 };
475 
476 template <typename T>
477 static inline T
478 fpAdd(T a, T b)
479 {
480  return a + b;
481 };
482 
483 template <typename T>
484 static inline T
485 fpSub(T a, T b)
486 {
487  return a - b;
488 };
489 
490 static inline float
491 fpAddS(float a, float b)
492 {
493  return a + b;
494 }
495 
496 static inline double
497 fpAddD(double a, double b)
498 {
499  return a + b;
500 }
501 
502 static inline float
503 fpSubS(float a, float b)
504 {
505  return a - b;
506 }
507 
508 static inline double
509 fpSubD(double a, double b)
510 {
511  return a - b;
512 }
513 
514 static inline float
515 fpDivS(float a, float b)
516 {
517  return a / b;
518 }
519 
520 static inline double
521 fpDivD(double a, double b)
522 {
523  return a / b;
524 }
525 
526 template <typename T>
527 static inline T
528 fpDiv(T a, T b)
529 {
530  return a / b;
531 };
532 
533 template <typename T>
534 static inline T
535 fpMulX(T a, T b)
536 {
537  uint64_t opData;
538  uint32_t sign1;
539  uint32_t sign2;
540  const bool single = (sizeof(T) == sizeof(float));
541  if (single) {
542  opData = (fpToBits(a));
543  sign1 = opData>>31;
544  opData = (fpToBits(b));
545  sign2 = opData>>31;
546  } else {
547  opData = (fpToBits(a));
548  sign1 = opData>>63;
549  opData = (fpToBits(b));
550  sign2 = opData>>63;
551  }
552  bool inf1 = (std::fpclassify(a) == FP_INFINITE);
553  bool inf2 = (std::fpclassify(b) == FP_INFINITE);
554  bool zero1 = (std::fpclassify(a) == FP_ZERO);
555  bool zero2 = (std::fpclassify(b) == FP_ZERO);
556  if ((inf1 && zero2) || (zero1 && inf2)) {
557  if (sign1 ^ sign2)
558  return (T)(-2.0);
559  else
560  return (T)(2.0);
561  } else {
562  return (a * b);
563  }
564 };
565 
566 
567 template <typename T>
568 static inline T
569 fpMul(T a, T b)
570 {
571  return a * b;
572 };
573 
574 static inline float
575 fpMulS(float a, float b)
576 {
577  return a * b;
578 }
579 
580 static inline double
581 fpMulD(double a, double b)
582 {
583  return a * b;
584 }
585 
586 template <typename T>
587 static inline T
588 // @todo remove this when all calls to it have been replaced with the new fplib implementation
589 fpMulAdd(T op1, T op2, T addend)
590 {
591  T result;
592 
593  if (sizeof(T) == sizeof(float))
594  result = fmaf(op1, op2, addend);
595  else
596  result = fma(op1, op2, addend);
597 
598  // ARM doesn't generate signed nan's from this opperation, so fix up the result
599  if (std::isnan(result) && !std::isnan(op1) &&
600  !std::isnan(op2) && !std::isnan(addend))
601  {
602  uint64_t bitMask = ULL(0x1) << ((sizeof(T) * 8) - 1);
603  result = bitsToFp(fpToBits(result) & ~bitMask, op1);
604  }
605  return result;
606 }
607 
608 template <typename T>
609 static inline T
610 fpRIntX(T a, FPSCR &fpscr)
611 {
612  T rVal;
613 
614  rVal = rint(a);
615  if (rVal != a && !std::isnan(a))
616  fpscr.ixc = 1;
617  return (rVal);
618 };
619 
620 template <typename T>
621 static inline T
622 fpMaxNum(T a, T b)
623 {
624  const bool single = (sizeof(T) == sizeof(float));
625  const uint64_t qnan = single ? 0x7fc00000 : ULL(0x7ff8000000000000);
626 
627  if (std::isnan(a))
628  return ((fpToBits(a) & qnan) == qnan) ? b : a;
629  if (std::isnan(b))
630  return ((fpToBits(b) & qnan) == qnan) ? a : b;
631  // Handle comparisons of +0 and -0.
632  if (!std::signbit(a) && std::signbit(b))
633  return a;
634  return fmax(a, b);
635 };
636 
637 template <typename T>
638 static inline T
639 fpMax(T a, T b)
640 {
641  if (std::isnan(a))
642  return a;
643  if (std::isnan(b))
644  return b;
645  return fpMaxNum<T>(a, b);
646 };
647 
648 template <typename T>
649 static inline T
650 fpMinNum(T a, T b)
651 {
652  const bool single = (sizeof(T) == sizeof(float));
653  const uint64_t qnan = single ? 0x7fc00000 : ULL(0x7ff8000000000000);
654 
655  if (std::isnan(a))
656  return ((fpToBits(a) & qnan) == qnan) ? b : a;
657  if (std::isnan(b))
658  return ((fpToBits(b) & qnan) == qnan) ? a : b;
659  // Handle comparisons of +0 and -0.
660  if (std::signbit(a) && !std::signbit(b))
661  return a;
662  return fmin(a, b);
663 };
664 
665 template <typename T>
666 static inline T
667 fpMin(T a, T b)
668 {
669  if (std::isnan(a))
670  return a;
671  if (std::isnan(b))
672  return b;
673  return fpMinNum<T>(a, b);
674 };
675 
676 template <typename T>
677 static inline T
678 fpRSqrts(T a, T b)
679 {
680  int fpClassA = std::fpclassify(a);
681  int fpClassB = std::fpclassify(b);
682  T aXb;
683  int fpClassAxB;
684 
685  if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
686  (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
687  return 1.5;
688  }
689  aXb = a*b;
690  fpClassAxB = std::fpclassify(aXb);
691  if (fpClassAxB == FP_SUBNORMAL) {
692  feraiseexcept(FeUnderflow);
693  return 1.5;
694  }
695  return (3.0 - (a * b)) / 2.0;
696 };
697 
698 template <typename T>
699 static inline T
700 fpRecps(T a, T b)
701 {
702  int fpClassA = std::fpclassify(a);
703  int fpClassB = std::fpclassify(b);
704  T aXb;
705  int fpClassAxB;
706 
707  if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
708  (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
709  return 2.0;
710  }
711  aXb = a*b;
712  fpClassAxB = std::fpclassify(aXb);
713  if (fpClassAxB == FP_SUBNORMAL) {
714  feraiseexcept(FeUnderflow);
715  return 2.0;
716  }
717  return 2.0 - (a * b);
718 };
719 
720 
721 static inline float
722 fpRSqrtsS(float a, float b)
723 {
724  int fpClassA = std::fpclassify(a);
725  int fpClassB = std::fpclassify(b);
726  float aXb;
727  int fpClassAxB;
728 
729  if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
730  (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
731  return 1.5;
732  }
733  aXb = a*b;
734  fpClassAxB = std::fpclassify(aXb);
735  if (fpClassAxB == FP_SUBNORMAL) {
736  feraiseexcept(FeUnderflow);
737  return 1.5;
738  }
739  return (3.0 - (a * b)) / 2.0;
740 }
741 
742 static inline float
743 fpRecpsS(float a, float b)
744 {
745  int fpClassA = std::fpclassify(a);
746  int fpClassB = std::fpclassify(b);
747  float aXb;
748  int fpClassAxB;
749 
750  if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
751  (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
752  return 2.0;
753  }
754  aXb = a*b;
755  fpClassAxB = std::fpclassify(aXb);
756  if (fpClassAxB == FP_SUBNORMAL) {
757  feraiseexcept(FeUnderflow);
758  return 2.0;
759  }
760  return 2.0 - (a * b);
761 }
762 
763 template <typename T>
764 static inline T
766  T val;
767 
768  val = round(a);
769  if (a - val == 0.5) {
770  if ( (((int) a) & 1) == 0 ) val += 1.0;
771  }
772  else if (a - val == -0.5) {
773  if ( (((int) a) & 1) == 0 ) val -= 1.0;
774  }
775  return val;
776 }
777 
778 
779 
780 class FpOp : public PredOp
781 {
782  protected:
783  FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
784  PredOp(mnem, _machInst, __opClass)
785  {}
786 
787  virtual float
788  doOp(float op1, float op2) const
789  {
790  panic("Unimplemented version of doOp called.\n");
791  }
792 
793  virtual float
794  doOp(float op1) const
795  {
796  panic("Unimplemented version of doOp called.\n");
797  }
798 
799  virtual double
800  doOp(double op1, double op2) const
801  {
802  panic("Unimplemented version of doOp called.\n");
803  }
804 
805  virtual double
806  doOp(double op1) const
807  {
808  panic("Unimplemented version of doOp called.\n");
809  }
810 
811  double
812  dbl(uint32_t low, uint32_t high) const
813  {
814  double junk = 0.0;
815  return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
816  }
817 
818  uint32_t
819  dblLow(double val) const
820  {
821  return fpToBits(val);
822  }
823 
824  uint32_t
825  dblHi(double val) const
826  {
827  return fpToBits(val) >> 32;
828  }
829 
830  template <class fpType>
831  fpType
832  processNans(FPSCR &fpscr, bool &done, bool defaultNan,
833  fpType op1, fpType op2) const;
834 
835  template <class fpType>
836  fpType
837  ternaryOp(FPSCR &fpscr, fpType op1, fpType op2, fpType op3,
838  fpType (*func)(fpType, fpType, fpType),
839  bool flush, bool defaultNan, uint32_t rMode) const;
840 
841  template <class fpType>
842  fpType
843  binaryOp(FPSCR &fpscr, fpType op1, fpType op2,
844  fpType (*func)(fpType, fpType),
845  bool flush, bool defaultNan, uint32_t rMode) const;
846 
847  template <class fpType>
848  fpType
849  unaryOp(FPSCR &fpscr, fpType op1,
850  fpType (*func)(fpType),
851  bool flush, uint32_t rMode) const;
852 
853  void
854  advancePC(PCState &pcState) const
855  {
856  if (flags[IsLastMicroop]) {
857  pcState.uEnd();
858  } else if (flags[IsMicroop]) {
859  pcState.uAdvance();
860  } else {
861  pcState.advance();
862  }
863  }
864 
865  float
866  fpSqrt (FPSCR fpscr,float x) const
867  {
868 
869  return unaryOp(fpscr,x,sqrtf,fpscr.fz,fpscr.rMode);
870 
871  }
872 
873  double
874  fpSqrt (FPSCR fpscr,double x) const
875  {
876 
877  return unaryOp(fpscr,x,sqrt,fpscr.fz,fpscr.rMode);
878 
879  }
880 };
881 
882 class FpCondCompRegOp : public FpOp
883 {
884  protected:
887  uint8_t defCc;
888 
889  FpCondCompRegOp(const char *mnem, ExtMachInst _machInst,
890  OpClass __opClass, IntRegIndex _op1, IntRegIndex _op2,
891  ConditionCode _condCode, uint8_t _defCc) :
892  FpOp(mnem, _machInst, __opClass),
893  op1(_op1), op2(_op2), condCode(_condCode), defCc(_defCc)
894  {}
895 
896  std::string generateDisassembly(
897  Addr pc, const SymbolTable *symtab) const override;
898 };
899 
900 class FpCondSelOp : public FpOp
901 {
902  protected:
903  IntRegIndex dest, op1, op2;
905 
906  FpCondSelOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
907  IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
908  ConditionCode _condCode) :
909  FpOp(mnem, _machInst, __opClass),
910  dest(_dest), op1(_op1), op2(_op2), condCode(_condCode)
911  {}
912 
913  std::string generateDisassembly(
914  Addr pc, const SymbolTable *symtab) const override;
915 };
916 
917 class FpRegRegOp : public FpOp
918 {
919  protected:
922 
923  FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
924  IntRegIndex _dest, IntRegIndex _op1,
926  FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1)
927  {
929  }
930 
931  std::string generateDisassembly(
932  Addr pc, const SymbolTable *symtab) const override;
933 };
934 
935 class FpRegImmOp : public FpOp
936 {
937  protected:
939  uint64_t imm;
940 
941  FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
942  IntRegIndex _dest, uint64_t _imm,
944  FpOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm)
945  {
947  }
948 
949  std::string generateDisassembly(
950  Addr pc, const SymbolTable *symtab) const override;
951 };
952 
953 class FpRegRegImmOp : public FpOp
954 {
955  protected:
958  uint64_t imm;
959 
960  FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
961  IntRegIndex _dest, IntRegIndex _op1,
962  uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) :
963  FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm)
964  {
966  }
967 
968  std::string generateDisassembly(
969  Addr pc, const SymbolTable *symtab) const override;
970 };
971 
972 class FpRegRegRegOp : public FpOp
973 {
974  protected:
978 
979  FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
980  IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
982  FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2)
983  {
985  }
986 
987  std::string generateDisassembly(
988  Addr pc, const SymbolTable *symtab) const override;
989 };
990 
991 class FpRegRegRegCondOp : public FpOp
992 {
993  protected:
998 
999  FpRegRegRegCondOp(const char *mnem, ExtMachInst _machInst,
1000  OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1,
1001  IntRegIndex _op2, ConditionCode _cond,
1003  FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2),
1004  cond(_cond)
1005  {
1007  }
1008 
1009  std::string generateDisassembly(
1010  Addr pc, const SymbolTable *symtab) const override;
1011 };
1012 
1013 class FpRegRegRegRegOp : public FpOp
1014 {
1015  protected:
1020 
1021  FpRegRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
1022  IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
1024  FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2),
1025  op3(_op3)
1026  {
1028  }
1029 
1030  std::string generateDisassembly(
1031  Addr pc, const SymbolTable *symtab) const override;
1032 };
1033 
1034 class FpRegRegRegImmOp : public FpOp
1035 {
1036  protected:
1040  uint64_t imm;
1041 
1042  FpRegRegRegImmOp(const char *mnem, ExtMachInst _machInst,
1043  OpClass __opClass, IntRegIndex _dest,
1044  IntRegIndex _op1, IntRegIndex _op2,
1045  uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) :
1046  FpOp(mnem, _machInst, __opClass),
1047  dest(_dest), op1(_op1), op2(_op2), imm(_imm)
1048  {
1050  }
1051 
1052  std::string generateDisassembly(
1053  Addr pc, const SymbolTable *symtab) const override;
1054 };
1055 
1056 }
1057 
1058 #endif //__ARCH_ARM_INSTS_VFP_HH__
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
double fixFpSFpDDest(FPSCR fpscr, float val)
Definition: vfp.cc:363
static float bitsToFp(uint64_t, float)
Definition: vfp.hh:180
fpType fixDivDest(bool flush, bool defaultNan, fpType val, fpType op1, fpType op2)
Definition: vfp.cc:292
static T fpMul(T a, T b)
Definition: vfp.hh:569
IntRegIndex op1
Definition: vfp.hh:1038
IntRegIndex
Definition: intregs.hh:53
static float fpDivS(float a, float b)
Definition: vfp.hh:515
double dbl(uint32_t low, uint32_t high) const
Definition: vfp.hh:812
uint32_t dblLow(double val) const
Definition: vfp.hh:819
IntRegIndex op2
Definition: vfp.hh:1018
static T fpRIntX(T a, FPSCR &fpscr)
Definition: vfp.hh:610
static T fpRSqrts(T a, T b)
Definition: vfp.hh:678
VfpMicroMode
Definition: vfp.hh:53
uint32_t unsignedRecipEstimate(uint32_t op)
Definition: vfp.cc:879
IntRegIndex dest
Definition: vfp.hh:1016
static double fpAddD(double a, double b)
Definition: vfp.hh:497
#define LL(N)
int64_t constant
Definition: types.hh:52
static void vfpFlushToZero(FPSCR &fpscr, fpType &op)
Definition: vfp.hh:140
Bitfield< 21, 20 > stride
static T fpMin(T a, T b)
Definition: vfp.hh:667
Bitfield< 8 > a
static T fpSub(T a, T b)
Definition: vfp.hh:485
float fixFpDFpSDest(FPSCR fpscr, double val)
Definition: vfp.cc:327
bool fpclassify(T src0, uint32_t src1)
Definition: decl.hh:537
Base class for predicated integer operations.
Definition: pred_inst.hh:211
static double makeDouble(uint32_t low, uint32_t high)
Definition: vfp.hh:239
static T fpMaxNum(T a, T b)
Definition: vfp.hh:622
static float fpRecpsS(float a, float b)
Definition: vfp.hh:743
Definition: ccregs.hh:42
uint16_t vcvtFpDFpH(FPSCR &fpscr, bool flush, bool defaultNan, uint32_t rMode, bool ahp, double op)
Definition: vfp.cc:575
static uint32_t lowFromDouble(double val)
Definition: vfp.hh:246
FpRegRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _op3, VfpMicroMode mode=VfpNotAMicroop)
Definition: vfp.hh:1021
Bitfield< 4, 0 > mode
double vcvtFpHFpD(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op)
Definition: vfp.cc:645
double fpSqrt(FPSCR fpscr, double x) const
Definition: vfp.hh:874
static T fpMinNum(T a, T b)
Definition: vfp.hh:650
uint16_t vcvtFpSFpH(FPSCR &fpscr, bool flush, bool defaultNan, uint32_t rMode, bool ahp, float op)
Definition: vfp.cc:567
FpCondSelOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _condCode)
Definition: vfp.hh:906
FPSCR fpStandardFPSCRValue(const FPSCR &fpscr)
Definition: vfp.cc:895
Bitfield< 63 > val
Definition: misc.hh:771
uint64_t vfpFpToFixed(T val, bool isSigned, uint8_t width, uint8_t imm, bool useRmode=true, VfpRoundingMode roundMode=VfpRoundZero, bool aarch64=false)
Definition: vfp.hh:265
FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, VfpMicroMode mode=VfpNotAMicroop)
Definition: vfp.hh:923
ConditionCode
Definition: ccregs.hh:64
uint32_t unsignedRSqrtEstimate(uint32_t op)
Definition: vfp.cc:804
static double fpSubD(double a, double b)
Definition: vfp.hh:509
Bitfield< 7 > b
float fprSqrtEstimate(FPSCR &fpscr, float op)
Definition: vfp.cc:761
virtual float doOp(float op1, float op2) const
Definition: vfp.hh:788
static double fpMulD(double a, double b)
Definition: vfp.hh:581
Bitfield< 26 > ahp
std::bitset< Num_Flags > flags
Flag values for this instruction.
Definition: static_inst.hh:97
VfpMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, bool _wide)
Definition: vfp.hh:465
Bitfield< 4 > pc
IntRegIndex op2
Definition: vfp.hh:885
static uint32_t fpToBits(float)
Definition: vfp.hh:156
virtual float doOp(float op1) const
Definition: vfp.hh:794
static bool inScalarBank(IntRegIndex idx)
Definition: vfp.hh:457
static float fpRSqrtsS(float a, float b)
Definition: vfp.hh:722
IntRegIndex dest
Definition: vfp.hh:920
static T roundNEven(T a)
Definition: vfp.hh:765
IntRegIndex dest
Definition: vfp.hh:938
ConditionCode cond
Definition: vfp.hh:997
static T fpAdd(T a, T b)
Definition: vfp.hh:478
static void setFPExceptions(int exceptions)
Definition: vfp.hh:258
void finishVfp(FPSCR &fpscr, VfpSavedState state, bool flush, FPSCR mask)
Definition: vfp.cc:195
IntRegIndex op1
Definition: vfp.hh:1017
static T fpMulAdd(T op1, T op2, T addend)
Definition: vfp.hh:589
virtual double doOp(double op1) const
Definition: vfp.hh:806
float fpSqrt(FPSCR fpscr, float x) const
Definition: vfp.hh:866
static float fpMulS(float a, float b)
Definition: vfp.hh:575
IntRegIndex dest
Definition: vfp.hh:1037
double vfpUFixedToFpD(bool flush, bool defaultNan, uint64_t val, uint8_t width, uint8_t imm)
Definition: vfp.cc:703
virtual double doOp(double op1, double op2) const
Definition: vfp.hh:800
static float fpSubS(float a, float b)
Definition: vfp.hh:503
static T fpMulX(T a, T b)
Definition: vfp.hh:535
uint64_t imm
Definition: vfp.hh:939
FpRegRegRegCondOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _cond, VfpMicroMode mode=VfpNotAMicroop)
Definition: vfp.hh:999
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
#define ULL(N)
uint64_t constant
Definition: types.hh:50
Bitfield< 7, 0 > imm
Definition: types.hh:142
IntRegIndex op1
Definition: vfp.hh:976
static double fpDivD(double a, double b)
Definition: vfp.hh:521
FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
Definition: vfp.hh:783
Bitfield< 34 > aarch64
Definition: types.hh:91
static bool isSnan(fpType val)
Definition: vfp.hh:205
double vfpSFixedToFpD(bool flush, bool defaultNan, int64_t val, uint8_t width, uint8_t imm)
Definition: vfp.cc:722
FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, VfpMicroMode mode=VfpNotAMicroop)
Definition: vfp.hh:979
IntRegIndex dest
Definition: vfp.hh:994
void nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2)
Definition: vfp.cc:1170
static T fpDiv(T a, T b)
Definition: vfp.hh:528
FeExceptionBit
Definition: vfp.hh:84
IntRegIndex op1
Definition: vfp.hh:957
FeRoundingMode
Definition: vfp.hh:94
IntRegIndex op3
Definition: vfp.hh:1019
fpType fixDest(bool flush, bool defaultNan, fpType val, fpType op1)
Definition: vfp.cc:221
IntRegIndex op1
Definition: vfp.hh:995
IntRegIndex op2
Definition: vfp.hh:903
Base class for predicated macro-operations.
Definition: pred_inst.hh:337
int signbit(uint64_t src, int sz)
Definition: hsail_code.hh:100
GenericISA::SimplePCState< MachInst > PCState
Definition: types.hh:43
VfpRoundingMode
Definition: vfp.hh:102
FpRegRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
Definition: vfp.hh:1042
float fpRecipEstimate(FPSCR &fpscr, float op)
Definition: vfp.cc:843
IntRegIndex op2
Definition: vfp.hh:996
VfpSavedState prepFpState(uint32_t rMode)
Definition: vfp.cc:173
IntRegIndex dest
Definition: vfp.hh:975
ConditionCode condCode
Definition: vfp.hh:904
Bitfield< 4 > width
uint64_t imm
Definition: vfp.hh:958
FpCondCompRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _condCode, uint8_t _defCc)
Definition: vfp.hh:889
static float fpAddS(float a, float b)
Definition: vfp.hh:491
float vcvtFpHFpS(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op)
Definition: vfp.cc:655
static void setVfpMicroFlags(VfpMicroMode mode, T &flags)
Definition: vfp.hh:62
ConditionCode condCode
Definition: vfp.hh:886
TheISA::ExtMachInst ExtMachInst
Binary extended machine instruction type.
Definition: static_inst.hh:87
IntRegIndex op2
Definition: vfp.hh:977
Bitfield< 3, 0 > mask
Definition: types.hh:64
static const uint32_t FpscrExcMask
Definition: miscregs.hh:1921
static uint32_t highFromDouble(double val)
Definition: vfp.hh:252
uint32_t dblHi(double val) const
Definition: vfp.hh:825
Bitfield< 4 > op
Definition: types.hh:80
float vfpUFixedToFpS(bool flush, bool defaultNan, uint64_t val, uint8_t width, uint8_t imm)
Definition: vfp.cc:665
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
IntRegIndex op2
Definition: vfp.hh:1039
static T fpMax(T a, T b)
Definition: vfp.hh:639
FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
Definition: vfp.hh:941
Bitfield< 19, 16 > fp
void advancePC(PCState &pcState) const
Definition: vfp.hh:854
IntRegIndex dest
Definition: vfp.hh:956
static T fpRecps(T a, T b)
Definition: vfp.hh:700
FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
Definition: vfp.hh:960
Bitfield< 1 > x
Definition: types.hh:105
Bitfield< 23, 22 > rMode
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition: pred_inst.cc:106
IntRegIndex op1
Definition: vfp.hh:921
float vfpSFixedToFpS(bool flush, bool defaultNan, int64_t val, uint8_t width, uint8_t imm)
Definition: vfp.cc:683
IntRegIndex addStride(IntRegIndex idx, unsigned stride)
Definition: vfp.cc:1157
int VfpSavedState
Definition: vfp.hh:213

Generated on Fri Feb 28 2020 16:26:57 for gem5 by doxygen 1.8.13