Go to the documentation of this file.
38 #ifndef __ARCH_ARM_INSTS_VFP_HH__
39 #define __ARCH_ARM_INSTS_VFP_HH__
64 flags[StaticInst::IsMicroop] =
true;
67 flags[StaticInst::IsMicroop] =
68 flags[StaticInst::IsFirstMicroop] =
true;
71 flags[StaticInst::IsMicroop] =
72 flags[StaticInst::IsLastMicroop] =
true;
78 flags[StaticInst::IsDelayedCommit] =
true;
109 static inline float bitsToFp(uint64_t,
float);
110 static inline double bitsToFp(uint64_t,
double);
111 static inline uint32_t
fpToBits(
float);
112 static inline uint64_t
fpToBits(
double);
114 template <
class fpType>
119 if (std::fpclassify(
op) == FP_SUBNORMAL) {
120 uint64_t bitMask =
ULL(0x1) << (
sizeof(fpType) * 8 - 1);
127 template <
class fpType>
133 return flush1 || flush2;
136 template <
class fpType>
145 template <
class fpType>
153 static inline uint32_t
165 static inline uint64_t
201 template <
class fpType>
205 const bool single = (
sizeof(fpType) ==
sizeof(
float));
206 const uint64_t qnan =
207 single ? 0x7fc00000 :
ULL(0x7ff8000000000000);
216 template <
class fpType>
217 fpType
fixDest(FPSCR fpscr, fpType
val, fpType op1);
219 template <
class fpType>
220 fpType
fixDest(FPSCR fpscr, fpType
val, fpType op1, fpType op2);
222 template <
class fpType>
223 fpType
fixDivDest(FPSCR fpscr, fpType
val, fpType op1, fpType op2);
228 uint16_t
vcvtFpSFpH(FPSCR &fpscr,
bool flush,
bool defaultNan,
230 uint16_t
vcvtFpDFpH(FPSCR &fpscr,
bool flush,
bool defaultNan,
233 float vcvtFpHFpS(FPSCR &fpscr,
bool defaultNan,
bool ahp, uint16_t
op);
234 double vcvtFpHFpD(FPSCR &fpscr,
bool defaultNan,
bool ahp, uint16_t
op);
240 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
243 static inline uint32_t
249 static inline uint32_t
258 feraiseexcept(exceptions);
261 template <
typename T>
268 bool roundAwayFix =
false;
271 rmode = fegetround();
294 panic(
"Unsupported roundMode %d\n", roundMode);
297 __asm__ __volatile__(
"" :
"=m" (rmode) :
"m" (rmode));
300 __asm__ __volatile__(
"" :
"=m" (
val) :
"m" (
val));
303 __asm__ __volatile__(
"" :
"=m" (
val) :
"m" (
val));
306 __asm__ __volatile__(
"" :
"=m" (
val) :
"m" (
val));
310 int fpType = std::fpclassify(
val);
311 if (fpType == FP_SUBNORMAL || fpType == FP_NAN) {
312 if (fpType == FP_NAN) {
316 }
else if (origVal !=
val) {
319 if (origVal -
val > 0.5)
321 else if (
val - origVal > 0.5)
330 volatile T error =
val;
333 if ( (error > 0.5) ||
334 ((error == 0.5) && (
val >= 0)) )
349 __asm__ __volatile__(
"" :
"=m" (
val) :
"m" (
val));
352 bool outOfRange =
false;
353 int64_t result = (int64_t)
val;
358 finalVal = (int16_t)
val;
359 }
else if (
width == 32) {
360 finalVal =(int32_t)
val;
361 }
else if (
width == 64) {
369 if ((
double)
val < minVal) {
374 if ((
double)
val > maxVal) {
379 bool isNeg =
val < 0;
384 outOfRange = ((uint64_t) result >> (
width - 1)) !=
391 outOfRange |=
val < result;
396 outOfRange |=
val > result;
411 if ((
double)
val < 0) {
457 return (idx % 32) < 8;
464 OpClass __opClass,
bool _wide) :
474 template <
typename T>
481 template <
typename T>
524 template <
typename T>
531 template <
typename T>
538 const bool single = (
sizeof(T) ==
sizeof(
float));
550 bool inf1 = (std::fpclassify(
a) == FP_INFINITE);
551 bool inf2 = (std::fpclassify(
b) == FP_INFINITE);
552 bool zero1 = (std::fpclassify(
a) == FP_ZERO);
553 bool zero2 = (std::fpclassify(
b) == FP_ZERO);
554 if ((inf1 && zero2) || (zero1 && inf2)) {
565 template <
typename T>
584 template <
typename T>
591 if (
sizeof(T) ==
sizeof(
float))
592 result = fmaf(op1, op2, addend);
594 result = fma(op1, op2, addend);
597 if (std::isnan(result) && !std::isnan(op1) &&
598 !std::isnan(op2) && !std::isnan(addend))
600 uint64_t bitMask =
ULL(0x1) << ((
sizeof(T) * 8) - 1);
606 template <
typename T>
613 if (rVal !=
a && !std::isnan(
a))
618 template <
typename T>
622 const bool single = (
sizeof(T) ==
sizeof(
float));
623 const uint64_t qnan = single ? 0x7fc00000 :
ULL(0x7ff8000000000000);
630 if (!std::signbit(
a) && std::signbit(
b))
635 template <
typename T>
643 return fpMaxNum<T>(
a,
b);
646 template <
typename T>
650 const bool single = (
sizeof(T) ==
sizeof(
float));
651 const uint64_t qnan = single ? 0x7fc00000 :
ULL(0x7ff8000000000000);
658 if (std::signbit(
a) && !std::signbit(
b))
663 template <
typename T>
671 return fpMinNum<T>(
a,
b);
674 template <
typename T>
678 int fpClassA = std::fpclassify(
a);
679 int fpClassB = std::fpclassify(
b);
683 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
684 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
688 fpClassAxB = std::fpclassify(aXb);
689 if (fpClassAxB == FP_SUBNORMAL) {
693 return (3.0 - (
a *
b)) / 2.0;
696 template <
typename T>
700 int fpClassA = std::fpclassify(
a);
701 int fpClassB = std::fpclassify(
b);
705 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
706 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
710 fpClassAxB = std::fpclassify(aXb);
711 if (fpClassAxB == FP_SUBNORMAL) {
715 return 2.0 - (
a *
b);
722 int fpClassA = std::fpclassify(
a);
723 int fpClassB = std::fpclassify(
b);
727 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
728 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
732 fpClassAxB = std::fpclassify(aXb);
733 if (fpClassAxB == FP_SUBNORMAL) {
737 return (3.0 - (
a *
b)) / 2.0;
743 int fpClassA = std::fpclassify(
a);
744 int fpClassB = std::fpclassify(
b);
748 if ((fpClassA == FP_ZERO && fpClassB == FP_INFINITE) ||
749 (fpClassA == FP_INFINITE && fpClassB == FP_ZERO)) {
753 fpClassAxB = std::fpclassify(aXb);
754 if (fpClassAxB == FP_SUBNORMAL) {
758 return 2.0 - (
a *
b);
761 template <
typename T>
767 if (
a -
val == 0.5) {
768 if ( (((
int)
a) & 1) == 0 )
val += 1.0;
770 else if (
a -
val == -0.5) {
771 if ( (((
int)
a) & 1) == 0 )
val -= 1.0;
782 PredOp(mnem, _machInst, __opClass)
786 doOp(
float op1,
float op2)
const
788 panic(
"Unimplemented version of doOp called.\n");
794 panic(
"Unimplemented version of doOp called.\n");
798 doOp(
double op1,
double op2)
const
800 panic(
"Unimplemented version of doOp called.\n");
806 panic(
"Unimplemented version of doOp called.\n");
810 dbl(uint32_t low, uint32_t high)
const
813 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk);
828 template <
class fpType>
830 processNans(FPSCR &fpscr,
bool &done,
bool defaultNan,
831 fpType op1, fpType op2)
const;
833 template <
class fpType>
835 ternaryOp(FPSCR &fpscr, fpType op1, fpType op2, fpType op3,
836 fpType (*func)(fpType, fpType, fpType),
837 bool flush,
bool defaultNan, uint32_t
rMode)
const;
839 template <
class fpType>
841 binaryOp(FPSCR &fpscr, fpType op1, fpType op2,
842 fpType (*func)(fpType, fpType),
843 bool flush,
bool defaultNan, uint32_t
rMode)
const;
845 template <
class fpType>
847 unaryOp(FPSCR &fpscr, fpType op1,
848 fpType (*func)(fpType),
849 bool flush, uint32_t
rMode)
const;
854 if (
flags[IsLastMicroop]) {
856 }
else if (
flags[IsMicroop]) {
867 return unaryOp(fpscr,
x,sqrtf,fpscr.fz,fpscr.rMode);
875 return unaryOp(fpscr,
x,sqrt,fpscr.fz,fpscr.rMode);
890 FpOp(mnem, _machInst, __opClass),
907 FpOp(mnem, _machInst, __opClass),
924 FpOp(mnem, _machInst, __opClass),
dest(_dest),
op1(_op1)
942 FpOp(mnem, _machInst, __opClass),
dest(_dest),
imm(_imm)
961 FpOp(mnem, _machInst, __opClass),
dest(_dest),
op1(_op1),
imm(_imm)
980 FpOp(mnem, _machInst, __opClass),
dest(_dest),
op1(_op1),
op2(_op2)
1001 FpOp(mnem, _machInst, __opClass),
dest(_dest),
op1(_op1),
op2(_op2),
1022 FpOp(mnem, _machInst, __opClass),
dest(_dest),
op1(_op1),
op2(_op2),
1044 FpOp(mnem, _machInst, __opClass),
1056 #endif //__ARCH_ARM_INSTS_VFP_HH__
virtual float doOp(float op1, float op2) const
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
uint16_t vcvtFpSFpH(FPSCR &fpscr, bool flush, bool defaultNan, uint32_t rMode, bool ahp, float op)
std::bitset< Num_Flags > flags
Flag values for this instruction.
virtual double doOp(double op1, double op2) const
static T fpMinNum(T a, T b)
static double fpMulD(double a, double b)
#define LL(N)
int64_t constant
fpType ternaryOp(FPSCR &fpscr, fpType op1, fpType op2, fpType op3, fpType(*func)(fpType, fpType, fpType), bool flush, bool defaultNan, uint32_t rMode) const
uint32_t dblLow(double val) const
static double makeDouble(uint32_t low, uint32_t high)
FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, VfpMicroMode mode=VfpNotAMicroop)
static float fpRecpsS(float a, float b)
float vfpSFixedToFpS(bool flush, bool defaultNan, int64_t val, uint8_t width, uint8_t imm)
static T fpRSqrts(T a, T b)
double fpSqrt(FPSCR fpscr, double x) const
FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
static T fpRIntX(T a, FPSCR &fpscr)
fpType unaryOp(FPSCR &fpscr, fpType op1, fpType(*func)(fpType), bool flush, uint32_t rMode) const
Base class for predicated integer operations.
static uint32_t lowFromDouble(double val)
static float bitsToFp(uint64_t, float)
uint64_t vfpFpToFixed(T val, bool isSigned, uint8_t width, uint8_t imm, bool useRmode=true, VfpRoundingMode roundMode=VfpRoundZero, bool aarch64=false)
static T fpMulX(T a, T b)
fpType processNans(FPSCR &fpscr, bool &done, bool defaultNan, fpType op1, fpType op2) const
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
uint32_t dblHi(double val) const
FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, VfpMicroMode mode=VfpNotAMicroop)
uint32_t unsignedRSqrtEstimate(uint32_t op)
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
static uint32_t fpToBits(float)
double fixFpSFpDDest(FPSCR fpscr, float val)
float fixFpDFpSDest(FPSCR fpscr, double val)
FpCondCompRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _condCode, uint8_t _defCc)
float fpRecipEstimate(FPSCR &fpscr, float op)
FPSCR fpStandardFPSCRValue(const FPSCR &fpscr)
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
FpRegRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
float vcvtFpHFpS(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op)
static float fpRSqrtsS(float a, float b)
static double fpSubD(double a, double b)
static T fpMaxNum(T a, T b)
static const uint32_t FpscrExcMask
static bool isSnan(fpType val)
void advancePC(PCState &pcState) const override
FpRegRegRegCondOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _cond, VfpMicroMode mode=VfpNotAMicroop)
uint16_t vcvtFpDFpH(FPSCR &fpscr, bool flush, bool defaultNan, uint32_t rMode, bool ahp, double op)
double vcvtFpHFpD(FPSCR &fpscr, bool defaultNan, bool ahp, uint16_t op)
Base class for predicated macro-operations.
static T fpRecps(T a, T b)
virtual float doOp(float op1) const
float fpSqrt(FPSCR fpscr, float x) const
TheISA::ExtMachInst ExtMachInst
Binary extended machine instruction type.
static bool inScalarBank(IntRegIndex idx)
double vfpSFixedToFpD(bool flush, bool defaultNan, int64_t val, uint8_t width, uint8_t imm)
static double fpDivD(double a, double b)
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, uint64_t _imm, VfpMicroMode mode=VfpNotAMicroop)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
IntRegIndex addStride(IntRegIndex idx, unsigned stride)
static float fpSubS(float a, float b)
VfpMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, bool _wide)
FpRegRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _op3, VfpMicroMode mode=VfpNotAMicroop)
float fprSqrtEstimate(FPSCR &fpscr, float op)
static void setFPExceptions(int exceptions)
GenericISA::DelaySlotPCState< MachInst > PCState
float vfpUFixedToFpS(bool flush, bool defaultNan, uint64_t val, uint8_t width, uint8_t imm)
std::string generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
static void setVfpMicroFlags(VfpMicroMode mode, T &flags)
fpType fixDivDest(bool flush, bool defaultNan, fpType val, fpType op1, fpType op2)
static float fpAddS(float a, float b)
double vfpUFixedToFpD(bool flush, bool defaultNan, uint64_t val, uint8_t width, uint8_t imm)
Bitfield< 21, 20 > stride
VfpSavedState prepFpState(uint32_t rMode)
void finishVfp(FPSCR &fpscr, VfpSavedState state, bool flush, FPSCR mask)
static uint32_t highFromDouble(double val)
static T fpMulAdd(T op1, T op2, T addend)
uint32_t unsignedRecipEstimate(uint32_t op)
static double fpAddD(double a, double b)
static void vfpFlushToZero(FPSCR &fpscr, fpType &op)
static float fpMulS(float a, float b)
fpType binaryOp(FPSCR &fpscr, fpType op1, fpType op2, fpType(*func)(fpType, fpType), bool flush, bool defaultNan, uint32_t rMode) const
double dbl(uint32_t low, uint32_t high) const
void nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2)
FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
static float fpDivS(float a, float b)
FpCondSelOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, ConditionCode _condCode)
fpType fixDest(bool flush, bool defaultNan, fpType val, fpType op1)
#define ULL(N)
uint64_t constant
#define panic(...)
This implements a cprintf based panic() function.
virtual double doOp(double op1) const
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Generated on Wed Sep 30 2020 14:02:00 for gem5 by doxygen 1.8.17