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

Generated on Mon May 26 2025 09:18:58 for gem5 by doxygen 1.13.2