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