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);
456 return (idx % 32) < 8;
463 OpClass __opClass,
bool _wide) :
473 template <
typename T>
480 template <
typename T>
523 template <
typename T>
530 template <
typename T>
537 const bool single = (
sizeof(T) ==
sizeof(
float));
553 if ((inf1 && zero2) || (zero1 && inf2)) {
564 template <
typename T>
583 template <
typename T>
590 if (
sizeof(T) ==
sizeof(
float))
591 result = fmaf(op1, op2, addend);
593 result = fma(op1, op2, addend);
596 if (std::isnan(result) && !std::isnan(op1) &&
597 !std::isnan(op2) && !std::isnan(addend))
599 uint64_t bitMask =
ULL(0x1) << ((
sizeof(T) * 8) - 1);
605 template <
typename T>
612 if (rVal != a && !std::isnan(a))
617 template <
typename T>
621 const bool single = (
sizeof(T) ==
sizeof(
float));
622 const uint64_t qnan = single ? 0x7fc00000 :
ULL(0x7ff8000000000000);
625 return ((
fpToBits(a) & qnan) == qnan) ? b :
a;
627 return ((
fpToBits(b) & qnan) == qnan) ? a :
b;
634 template <
typename T>
642 return fpMaxNum<T>(
a,
b);
645 template <
typename T>
649 const bool single = (
sizeof(T) ==
sizeof(
float));
650 const uint64_t qnan = single ? 0x7fc00000 :
ULL(0x7ff8000000000000);
653 return ((
fpToBits(a) & qnan) == qnan) ? b :
a;
655 return ((
fpToBits(b) & qnan) == qnan) ? a :
b;
662 template <
typename T>
670 return fpMinNum<T>(
a,
b);
673 template <
typename T>
682 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
683 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
688 if (fpClassAxB == FP_SUBNORMAL) {
692 return (3.0 - (a * b)) / 2.0;
695 template <
typename T>
704 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
705 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
710 if (fpClassAxB == FP_SUBNORMAL) {
714 return 2.0 - (a *
b);
726 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
727 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
732 if (fpClassAxB == FP_SUBNORMAL) {
736 return (3.0 - (a * b)) / 2.0;
747 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
748 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
753 if (fpClassAxB == FP_SUBNORMAL) {
757 return 2.0 - (a *
b);
760 template <
typename T>
766 if (a - val == 0.5) {
767 if ( (((
int) a) & 1) == 0 ) val += 1.0;
769 else if (a - val == -0.5) {
770 if ( (((
int) a) & 1) == 0 ) val -= 1.0;
781 PredOp(mnem, _machInst, __opClass)
785 doOp(
float op1,
float op2)
const
787 panic(
"Unimplemented version of doOp called.\n");
793 panic(
"Unimplemented version of doOp called.\n");
797 doOp(
double op1,
double op2)
const
799 panic(
"Unimplemented version of doOp called.\n");
805 panic(
"Unimplemented version of doOp called.\n");
809 dbl(uint32_t low, uint32_t high)
const
812 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
827 template <
class fpType>
829 processNans(FPSCR &fpscr,
bool &done,
bool defaultNan,
830 fpType op1, fpType op2)
const;
832 template <
class fpType>
834 ternaryOp(FPSCR &fpscr, fpType op1, fpType op2, fpType op3,
835 fpType (*func)(fpType, fpType, fpType),
836 bool flush,
bool defaultNan, uint32_t
rMode)
const;
838 template <
class fpType>
840 binaryOp(FPSCR &fpscr, fpType op1, fpType op2,
841 fpType (*func)(fpType, fpType),
842 bool flush,
bool defaultNan, uint32_t
rMode)
const;
844 template <
class fpType>
846 unaryOp(FPSCR &fpscr, fpType op1,
847 fpType (*func)(fpType),
848 bool flush, uint32_t
rMode)
const;
853 if (
flags[IsLastMicroop]) {
855 }
else if (
flags[IsMicroop]) {
866 return unaryOp(fpscr,x,sqrtf,fpscr.fz,fpscr.rMode);
874 return unaryOp(fpscr,x,sqrt,fpscr.fz,fpscr.rMode);
889 FpOp(mnem, _machInst, __opClass),
905 FpOp(mnem, _machInst, __opClass),
921 FpOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1)
938 FpOp(mnem, _machInst, __opClass),
dest(_dest),
imm(_imm)
956 FpOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1),
imm(_imm)
974 FpOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), op2(_op2)
994 FpOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), op2(_op2),
1014 FpOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), op2(_op2),
1035 FpOp(mnem, _machInst, __opClass),
1036 dest(_dest), op1(_op1), op2(_op2),
imm(_imm)
1046 #endif //__ARCH_ARM_INSTS_VFP_HH__
virtual double doOp(double op1, double op2) const
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)
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
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
double dbl(uint32_t low, uint32_t high) const
static void vfpFlushToZero(FPSCR &fpscr, fpType &op)
uint32_t dblHi(double val) const
void advancePC(PCState &pcState) const
Bitfield< 21, 20 > stride
float fixFpDFpSDest(FPSCR fpscr, double val)
bool fpclassify(T src0, uint32_t src1)
uint32_t dblLow(double val) const
Base class for predicated integer operations.
static double makeDouble(uint32_t low, uint32_t high)
virtual double doOp(double op1) const
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)
fpType ternaryOp(FPSCR &fpscr, fpType op1, fpType op2, fpType op3, fpType(*func)(fpType, fpType, fpType), bool flush, bool defaultNan, uint32_t rMode) const
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)
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)
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)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
float fprSqrtEstimate(FPSCR &fpscr, float op)
static double fpMulD(double a, double b)
float fpSqrt(FPSCR fpscr, float x) const
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)
static bool inScalarBank(IntRegIndex idx)
static float fpRSqrtsS(float a, float b)
double fpSqrt(FPSCR fpscr, double x) const
static void setFPExceptions(int exceptions)
void finishVfp(FPSCR &fpscr, VfpSavedState state, bool flush, FPSCR mask)
static T fpMulAdd(T op1, T op2, T addend)
static float fpMulS(float a, float b)
double vfpUFixedToFpD(bool flush, bool defaultNan, uint64_t val, uint8_t width, uint8_t imm)
static float fpSubS(float a, float b)
static T fpMulX(T a, T b)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
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)
virtual float doOp(float op1) const
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
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)
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
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
fpType binaryOp(FPSCR &fpscr, fpType op1, fpType op2, fpType(*func)(fpType, fpType), bool flush, bool defaultNan, uint32_t rMode) const
FpRegRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
fpType unaryOp(FPSCR &fpscr, fpType op1, fpType(*func)(fpType), bool flush, uint32_t rMode) const
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)
virtual float doOp(float op1, float op2) const
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.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
static const uint32_t FpscrExcMask
static uint32_t highFromDouble(double val)
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)
static T fpRecps(T a, T b)
fpType processNans(FPSCR &fpscr, bool &done, bool defaultNan, fpType op1, fpType op2) const
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
Internal function to generate disassembly string.
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
Internal function to generate disassembly string.
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const
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)