40 #ifndef __ARCH_ARM_INSTS_VFP_HH__ 41 #define __ARCH_ARM_INSTS_VFP_HH__ 66 flags[StaticInst::IsMicroop] =
true;
69 flags[StaticInst::IsMicroop] =
70 flags[StaticInst::IsFirstMicroop] =
true;
73 flags[StaticInst::IsMicroop] =
74 flags[StaticInst::IsLastMicroop] =
true;
80 flags[StaticInst::IsDelayedCommit] =
true;
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);
116 template <
class fpType>
122 uint64_t bitMask =
ULL(0x1) << (
sizeof(fpType) * 8 - 1);
129 template <
class fpType>
135 return flush1 || flush2;
138 template <
class fpType>
147 template <
class fpType>
155 static inline uint32_t
167 static inline uint64_t
203 template <
class fpType>
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);
218 template <
class fpType>
219 fpType
fixDest(FPSCR fpscr, fpType
val, fpType op1);
221 template <
class fpType>
222 fpType
fixDest(FPSCR fpscr, fpType
val, fpType op1, fpType op2);
224 template <
class fpType>
225 fpType
fixDivDest(FPSCR fpscr, fpType
val, fpType op1, fpType op2);
230 uint16_t
vcvtFpSFpH(FPSCR &fpscr,
bool flush,
bool defaultNan,
232 uint16_t
vcvtFpDFpH(FPSCR &fpscr,
bool flush,
bool defaultNan,
235 float vcvtFpHFpS(FPSCR &fpscr,
bool defaultNan,
bool ahp, uint16_t
op);
236 double vcvtFpHFpD(FPSCR &fpscr,
bool defaultNan,
bool ahp, uint16_t
op);
242 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
245 static inline uint32_t
251 static inline uint32_t
260 feraiseexcept(exceptions);
263 template <
typename T>
270 bool roundAwayFix =
false;
273 rmode = fegetround();
296 panic(
"Unsupported roundMode %d\n", roundMode);
299 __asm__ __volatile__(
"" :
"=m" (rmode) :
"m" (rmode));
301 val = val * pow(2.0, imm);
302 __asm__ __volatile__(
"" :
"=m" (val) :
"m" (val));
305 __asm__ __volatile__(
"" :
"=m" (val) :
"m" (val));
308 __asm__ __volatile__(
"" :
"=m" (val) :
"m" (val));
313 if (fpType == FP_SUBNORMAL || fpType == FP_NAN) {
314 if (fpType == FP_NAN) {
318 }
else if (origVal != val) {
321 if (origVal - val > 0.5)
323 else if (val - origVal > 0.5)
332 volatile T error =
val;
335 if ( (error > 0.5) ||
336 ((error == 0.5) && (val >= 0)) )
351 __asm__ __volatile__(
"" :
"=m" (val) :
"m" (val));
354 bool outOfRange =
false;
355 int64_t result = (int64_t) val;
360 finalVal = (int16_t)val;
361 }
else if (width == 32) {
362 finalVal =(int32_t)val;
363 }
else if (width == 64) {
366 panic(
"Unsupported width %d\n", width);
370 int64_t minVal = ~
mask(width-1);
371 if ((
double)val < minVal) {
375 int64_t maxVal =
mask(width-1);
376 if ((
double)val > maxVal) {
381 bool isNeg = val < 0;
382 finalVal = result &
mask(width);
386 outOfRange = ((uint64_t) result >> (width - 1)) !=
387 (isNeg ?
mask(64-width+1) : 0);
393 outOfRange |= val < result;
395 finalVal = 1
LL << (width-1);
398 outOfRange |= val > result;
400 finalVal =
mask(width-1);
413 if ((
double)val < 0) {
420 uint64_t result = ((uint64_t) val) &
mask(width);
437 int64_t val, uint8_t width, uint8_t imm);
440 uint64_t val, uint8_t width, uint8_t imm);
442 int64_t val, uint8_t width, uint8_t imm);
459 return (idx % 32) < 8;
466 OpClass __opClass,
bool _wide) :
467 PredMacroOp(mnem, _machInst, __opClass), wide(_wide)
476 template <
typename T>
483 template <
typename T>
526 template <
typename T>
533 template <
typename T>
540 const bool single = (
sizeof(T) ==
sizeof(
float));
556 if ((inf1 && zero2) || (zero1 && inf2)) {
567 template <
typename T>
586 template <
typename T>
593 if (
sizeof(T) ==
sizeof(
float))
594 result = fmaf(op1, op2, addend);
596 result = fma(op1, op2, addend);
599 if (std::isnan(result) && !std::isnan(op1) &&
600 !std::isnan(op2) && !std::isnan(addend))
602 uint64_t bitMask =
ULL(0x1) << ((
sizeof(T) * 8) - 1);
608 template <
typename T>
615 if (rVal != a && !std::isnan(a))
620 template <
typename T>
624 const bool single = (
sizeof(T) ==
sizeof(
float));
625 const uint64_t qnan = single ? 0x7fc00000 :
ULL(0x7ff8000000000000);
628 return ((
fpToBits(a) & qnan) == qnan) ?
b :
a;
630 return ((
fpToBits(b) & qnan) == qnan) ?
a :
b;
637 template <
typename T>
645 return fpMaxNum<T>(
a,
b);
648 template <
typename T>
652 const bool single = (
sizeof(T) ==
sizeof(
float));
653 const uint64_t qnan = single ? 0x7fc00000 :
ULL(0x7ff8000000000000);
656 return ((
fpToBits(a) & qnan) == qnan) ?
b :
a;
658 return ((
fpToBits(b) & qnan) == qnan) ?
a :
b;
665 template <
typename T>
673 return fpMinNum<T>(
a,
b);
676 template <
typename T>
685 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
686 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
691 if (fpClassAxB == FP_SUBNORMAL) {
695 return (3.0 - (a * b)) / 2.0;
698 template <
typename T>
707 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
708 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
713 if (fpClassAxB == FP_SUBNORMAL) {
717 return 2.0 - (a *
b);
729 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
730 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
735 if (fpClassAxB == FP_SUBNORMAL) {
739 return (3.0 - (a * b)) / 2.0;
750 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
751 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
756 if (fpClassAxB == FP_SUBNORMAL) {
760 return 2.0 - (a *
b);
763 template <
typename T>
769 if (a - val == 0.5) {
770 if ( (((
int) a) & 1) == 0 ) val += 1.0;
772 else if (a - val == -0.5) {
773 if ( (((
int) a) & 1) == 0 ) val -= 1.0;
784 PredOp(mnem, _machInst, __opClass)
788 doOp(
float op1,
float op2)
const 790 panic(
"Unimplemented version of doOp called.\n");
796 panic(
"Unimplemented version of doOp called.\n");
800 doOp(
double op1,
double op2)
const 802 panic(
"Unimplemented version of doOp called.\n");
808 panic(
"Unimplemented version of doOp called.\n");
812 dbl(uint32_t low, uint32_t high)
const 815 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
830 template <
class fpType>
832 processNans(FPSCR &fpscr,
bool &done,
bool defaultNan,
833 fpType op1, fpType op2)
const;
835 template <
class 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;
841 template <
class fpType>
843 binaryOp(FPSCR &fpscr, fpType op1, fpType op2,
844 fpType (*func)(fpType, fpType),
845 bool flush,
bool defaultNan, uint32_t rMode)
const;
847 template <
class fpType>
849 unaryOp(FPSCR &fpscr, fpType op1,
850 fpType (*func)(fpType),
851 bool flush, uint32_t rMode)
const;
856 if (
flags[IsLastMicroop]) {
858 }
else if (
flags[IsMicroop]) {
869 return unaryOp(fpscr,x,sqrtf,fpscr.fz,fpscr.rMode);
877 return unaryOp(fpscr,x,sqrt,fpscr.fz,fpscr.rMode);
892 FpOp(mnem, _machInst, __opClass),
893 op1(_op1), op2(_op2), condCode(_condCode), defCc(_defCc)
909 FpOp(mnem, _machInst, __opClass),
910 dest(_dest), op1(_op1), op2(_op2), condCode(_condCode)
926 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1)
944 FpOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm)
963 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm)
982 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2)
1003 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2),
1024 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2),
1046 FpOp(mnem, _machInst, __opClass),
1047 dest(_dest), op1(_op1), op2(_op2), imm(_imm)
1058 #endif //__ARCH_ARM_INSTS_VFP_HH__ #define panic(...)
This implements a cprintf based panic() function.
double fixFpSFpDDest(FPSCR fpscr, float val)
static float bitsToFp(uint64_t, float)
fpType fixDivDest(bool flush, bool defaultNan, fpType val, fpType op1, fpType op2)
static float fpDivS(float a, float b)
double dbl(uint32_t low, uint32_t high) const
uint32_t dblLow(double val) const
static T fpRIntX(T a, FPSCR &fpscr)
static T fpRSqrts(T a, T b)
uint32_t unsignedRecipEstimate(uint32_t op)
static double fpAddD(double a, double b)
#define LL(N)
int64_t constant
static void vfpFlushToZero(FPSCR &fpscr, fpType &op)
Bitfield< 21, 20 > stride
float fixFpDFpSDest(FPSCR fpscr, double val)
bool fpclassify(T src0, uint32_t src1)
Base class for predicated integer operations.
static double makeDouble(uint32_t low, uint32_t high)
static T fpMaxNum(T a, T b)
static float fpRecpsS(float a, float b)
uint16_t vcvtFpDFpH(FPSCR &fpscr, bool flush, bool defaultNan, uint32_t rMode, bool ahp, double op)
static uint32_t lowFromDouble(double val)
FpRegRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _op3, VfpMicroMode mode=VfpNotAMicroop)
double vcvtFpHFpD(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op)
double fpSqrt(FPSCR fpscr, double x) const
static T fpMinNum(T a, T b)
uint16_t vcvtFpSFpH(FPSCR &fpscr, bool flush, bool defaultNan, uint32_t rMode, bool ahp, float op)
FpCondSelOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _condCode)
FPSCR fpStandardFPSCRValue(const FPSCR &fpscr)
uint64_t vfpFpToFixed(T val, bool isSigned, uint8_t width, uint8_t imm, bool useRmode=true, VfpRoundingMode roundMode=VfpRoundZero, bool aarch64=false)
FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, VfpMicroMode mode=VfpNotAMicroop)
uint32_t unsignedRSqrtEstimate(uint32_t op)
static double fpSubD(double a, double b)
float fprSqrtEstimate(FPSCR &fpscr, float op)
virtual float doOp(float op1, float op2) const
static double fpMulD(double a, double b)
std::bitset< Num_Flags > flags
Flag values for this instruction.
VfpMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, bool _wide)
static uint32_t fpToBits(float)
virtual float doOp(float op1) const
static bool inScalarBank(IntRegIndex idx)
static float fpRSqrtsS(float a, float b)
static void setFPExceptions(int exceptions)
void finishVfp(FPSCR &fpscr, VfpSavedState state, bool flush, FPSCR mask)
static T fpMulAdd(T op1, T op2, T addend)
virtual double doOp(double op1) const
float fpSqrt(FPSCR fpscr, float x) const
static float fpMulS(float a, float b)
double vfpUFixedToFpD(bool flush, bool defaultNan, uint64_t val, uint8_t width, uint8_t imm)
virtual double doOp(double op1, double op2) const
static float fpSubS(float a, float b)
static T fpMulX(T a, T b)
FpRegRegRegCondOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _cond, VfpMicroMode mode=VfpNotAMicroop)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
#define ULL(N)
uint64_t constant
static double fpDivD(double a, double b)
FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
static bool isSnan(fpType val)
double vfpSFixedToFpD(bool flush, bool defaultNan, int64_t val, uint8_t width, uint8_t imm)
FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, VfpMicroMode mode=VfpNotAMicroop)
void nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2)
fpType fixDest(bool flush, bool defaultNan, fpType val, fpType op1)
Base class for predicated macro-operations.
int signbit(uint64_t src, int sz)
GenericISA::SimplePCState< MachInst > PCState
FpRegRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
float fpRecipEstimate(FPSCR &fpscr, float op)
VfpSavedState prepFpState(uint32_t rMode)
FpCondCompRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _condCode, uint8_t _defCc)
static float fpAddS(float a, float b)
float vcvtFpHFpS(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op)
static void setVfpMicroFlags(VfpMicroMode mode, T &flags)
TheISA::ExtMachInst ExtMachInst
Binary extended machine instruction type.
static const uint32_t FpscrExcMask
static uint32_t highFromDouble(double val)
uint32_t dblHi(double val) const
float vfpUFixedToFpS(bool flush, bool defaultNan, uint64_t val, uint8_t width, uint8_t imm)
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
void advancePC(PCState &pcState) const
static T fpRecps(T a, T b)
FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const override
Internal function to generate disassembly string.
float vfpSFixedToFpS(bool flush, bool defaultNan, int64_t val, uint8_t width, uint8_t imm)
IntRegIndex addStride(IntRegIndex idx, unsigned stride)