ARM: Add code to extract and record VFP exceptions.

This commit is contained in:
Gabe Black 2010-06-02 12:58:14 -05:00
parent e478df35f5
commit 86a1093992
2 changed files with 135 additions and 0 deletions

View file

@ -41,6 +41,8 @@
#define __ARCH_ARM_INSTS_VFP_HH__ #define __ARCH_ARM_INSTS_VFP_HH__
#include "arch/arm/insts/misc.hh" #include "arch/arm/insts/misc.hh"
#include "arch/arm/miscregs.hh"
#include <fenv.h>
enum VfpMicroMode { enum VfpMicroMode {
VfpNotAMicroop, VfpNotAMicroop,
@ -73,6 +75,79 @@ setVfpMicroFlags(VfpMicroMode mode, T &flags)
} }
} }
enum FeExceptionBit
{
FeDivByZero = FE_DIVBYZERO,
FeInexact = FE_INEXACT,
FeInvalid = FE_INVALID,
FeOverflow = FE_OVERFLOW,
FeUnderflow = FE_UNDERFLOW,
FeAllExceptions = FE_ALL_EXCEPT
};
enum FeRoundingMode
{
FeRoundDown = FE_DOWNWARD,
FeRoundNearest = FE_TONEAREST,
FeRoundZero = FE_TOWARDZERO,
FeRoundUpward = FE_UPWARD
};
enum VfpRoundingMode
{
VfpRoundNearest = 0,
VfpRoundUpward = 1,
VfpRoundDown = 2,
VfpRoundZero = 3
};
typedef int VfpSavedState;
static inline VfpSavedState
prepVfpFpscr(FPSCR fpscr)
{
int roundingMode = fegetround();
feclearexcept(FeAllExceptions);
switch (fpscr.rMode) {
case VfpRoundNearest:
fesetround(FeRoundNearest);
break;
case VfpRoundUpward:
fesetround(FeRoundUpward);
break;
case VfpRoundDown:
fesetround(FeRoundDown);
break;
case VfpRoundZero:
fesetround(FeRoundZero);
break;
}
return roundingMode;
}
static inline FPSCR
setVfpFpscr(FPSCR fpscr, VfpSavedState state)
{
int exceptions = fetestexcept(FeAllExceptions);
if (exceptions & FeInvalid) {
fpscr.ioc = 1;
}
if (exceptions & FeDivByZero) {
fpscr.dzc = 1;
}
if (exceptions & FeOverflow) {
fpscr.ofc = 1;
}
if (exceptions & FeUnderflow) {
fpscr.ufc = 1;
}
if (exceptions & FeInexact) {
fpscr.ixc = 1;
}
fesetround(state);
return fpscr;
}
class VfpMacroOp : public PredMacroOp class VfpMacroOp : public PredMacroOp
{ {
public: public:

View file

@ -376,7 +376,9 @@ let {{
exec_output += PredOpExecute.subst(vmov2Core2RegIop); exec_output += PredOpExecute.subst(vmov2Core2RegIop);
vmulSCode = ''' vmulSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest = FpOp1 * FpOp2; FpDest = FpOp1 * FpOp2;
Fpscr = setVfpFpscr(Fpscr, state);
if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
FpDest = NAN; FpDest = NAN;
} }
@ -392,7 +394,9 @@ let {{
IntDoubleUnion cOp1, cOp2, cDest; IntDoubleUnion cOp1, cOp2, cDest;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
cDest.fp = cOp1.fp * cOp2.fp; cDest.fp = cOp1.fp * cOp2.fp;
Fpscr = setVfpFpscr(Fpscr, state);
if ((isinf(cOp1.fp) && cOp2.fp == 0) || if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
(isinf(cOp2.fp) && cOp1.fp == 0)) { (isinf(cOp2.fp) && cOp1.fp == 0)) {
cDest.fp = NAN; cDest.fp = NAN;
@ -456,7 +460,9 @@ let {{
exec_output += PredOpExecute.subst(vabsDIop); exec_output += PredOpExecute.subst(vabsDIop);
vaddSCode = ''' vaddSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest = FpOp1 + FpOp2; FpDest = FpOp1 + FpOp2;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vaddSIop = InstObjParams("vadds", "VaddS", "VfpRegRegRegOp", vaddSIop = InstObjParams("vadds", "VaddS", "VfpRegRegRegOp",
{ "code": vaddSCode, { "code": vaddSCode,
@ -469,7 +475,9 @@ let {{
IntDoubleUnion cOp1, cOp2, cDest; IntDoubleUnion cOp1, cOp2, cDest;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
cDest.fp = cOp1.fp + cOp2.fp; cDest.fp = cOp1.fp + cOp2.fp;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -481,7 +489,9 @@ let {{
exec_output += PredOpExecute.subst(vaddDIop); exec_output += PredOpExecute.subst(vaddDIop);
vsubSCode = ''' vsubSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest = FpOp1 - FpOp2; FpDest = FpOp1 - FpOp2;
Fpscr = setVfpFpscr(Fpscr, state)
''' '''
vsubSIop = InstObjParams("vsubs", "VsubS", "VfpRegRegRegOp", vsubSIop = InstObjParams("vsubs", "VsubS", "VfpRegRegRegOp",
{ "code": vsubSCode, { "code": vsubSCode,
@ -494,7 +504,9 @@ let {{
IntDoubleUnion cOp1, cOp2, cDest; IntDoubleUnion cOp1, cOp2, cDest;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
cDest.fp = cOp1.fp - cOp2.fp; cDest.fp = cOp1.fp - cOp2.fp;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -506,7 +518,9 @@ let {{
exec_output += PredOpExecute.subst(vsubDIop); exec_output += PredOpExecute.subst(vsubDIop);
vdivSCode = ''' vdivSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest = FpOp1 / FpOp2; FpDest = FpOp1 / FpOp2;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vdivSIop = InstObjParams("vdivs", "VdivS", "VfpRegRegRegOp", vdivSIop = InstObjParams("vdivs", "VdivS", "VfpRegRegRegOp",
{ "code": vdivSCode, { "code": vdivSCode,
@ -519,7 +533,9 @@ let {{
IntDoubleUnion cOp1, cOp2, cDest; IntDoubleUnion cOp1, cOp2, cDest;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
cDest.fp = cOp1.fp / cOp2.fp; cDest.fp = cOp1.fp / cOp2.fp;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -531,7 +547,9 @@ let {{
exec_output += PredOpExecute.subst(vdivDIop); exec_output += PredOpExecute.subst(vdivDIop);
vsqrtSCode = ''' vsqrtSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest = sqrtf(FpOp1); FpDest = sqrtf(FpOp1);
Fpscr = setVfpFpscr(Fpscr, state);
if (FpOp1 < 0) { if (FpOp1 < 0) {
FpDest = NAN; FpDest = NAN;
} }
@ -546,7 +564,9 @@ let {{
vsqrtDCode = ''' vsqrtDCode = '''
IntDoubleUnion cOp1, cDest; IntDoubleUnion cOp1, cDest;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
cDest.fp = sqrt(cOp1.fp); cDest.fp = sqrt(cOp1.fp);
Fpscr = setVfpFpscr(Fpscr, state);
if (cOp1.fp < 0) { if (cOp1.fp < 0) {
cDest.fp = NAN; cDest.fp = NAN;
} }
@ -561,11 +581,13 @@ let {{
exec_output += PredOpExecute.subst(vsqrtDIop); exec_output += PredOpExecute.subst(vsqrtDIop);
vmlaSCode = ''' vmlaSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
float mid = FpOp1 * FpOp2; float mid = FpOp1 * FpOp2;
if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
mid = NAN; mid = NAN;
} }
FpDest = FpDest + mid; FpDest = FpDest + mid;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vmlaSIop = InstObjParams("vmlas", "VmlaS", "VfpRegRegRegOp", vmlaSIop = InstObjParams("vmlas", "VmlaS", "VfpRegRegRegOp",
{ "code": vmlaSCode, { "code": vmlaSCode,
@ -579,12 +601,14 @@ let {{
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
double mid = cOp1.fp * cOp2.fp; double mid = cOp1.fp * cOp2.fp;
if ((isinf(cOp1.fp) && cOp2.fp == 0) || if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
(isinf(cOp2.fp) && cOp1.fp == 0)) { (isinf(cOp2.fp) && cOp1.fp == 0)) {
mid = NAN; mid = NAN;
} }
cDest.fp = cDest.fp + mid; cDest.fp = cDest.fp + mid;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -596,11 +620,13 @@ let {{
exec_output += PredOpExecute.subst(vmlaDIop); exec_output += PredOpExecute.subst(vmlaDIop);
vmlsSCode = ''' vmlsSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
float mid = FpOp1 * FpOp2; float mid = FpOp1 * FpOp2;
if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
mid = NAN; mid = NAN;
} }
FpDest = FpDest - mid; FpDest = FpDest - mid;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vmlsSIop = InstObjParams("vmlss", "VmlsS", "VfpRegRegRegOp", vmlsSIop = InstObjParams("vmlss", "VmlsS", "VfpRegRegRegOp",
{ "code": vmlsSCode, { "code": vmlsSCode,
@ -614,12 +640,14 @@ let {{
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
double mid = cOp1.fp * cOp2.fp; double mid = cOp1.fp * cOp2.fp;
if ((isinf(cOp1.fp) && cOp2.fp == 0) || if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
(isinf(cOp2.fp) && cOp1.fp == 0)) { (isinf(cOp2.fp) && cOp1.fp == 0)) {
mid = NAN; mid = NAN;
} }
cDest.fp = cDest.fp - mid; cDest.fp = cDest.fp - mid;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -631,11 +659,13 @@ let {{
exec_output += PredOpExecute.subst(vmlsDIop); exec_output += PredOpExecute.subst(vmlsDIop);
vnmlaSCode = ''' vnmlaSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
float mid = FpOp1 * FpOp2; float mid = FpOp1 * FpOp2;
if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
mid = NAN; mid = NAN;
} }
FpDest = -FpDest - mid; FpDest = -FpDest - mid;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "VfpRegRegRegOp", vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "VfpRegRegRegOp",
{ "code": vnmlaSCode, { "code": vnmlaSCode,
@ -649,12 +679,14 @@ let {{
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
double mid = cOp1.fp * cOp2.fp; double mid = cOp1.fp * cOp2.fp;
if ((isinf(cOp1.fp) && cOp2.fp == 0) || if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
(isinf(cOp2.fp) && cOp1.fp == 0)) { (isinf(cOp2.fp) && cOp1.fp == 0)) {
mid = NAN; mid = NAN;
} }
cDest.fp = -cDest.fp - mid; cDest.fp = -cDest.fp - mid;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -666,11 +698,13 @@ let {{
exec_output += PredOpExecute.subst(vnmlaDIop); exec_output += PredOpExecute.subst(vnmlaDIop);
vnmlsSCode = ''' vnmlsSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
float mid = FpOp1 * FpOp2; float mid = FpOp1 * FpOp2;
if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
mid = NAN; mid = NAN;
} }
FpDest = -FpDest + mid; FpDest = -FpDest + mid;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "VfpRegRegRegOp", vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "VfpRegRegRegOp",
{ "code": vnmlsSCode, { "code": vnmlsSCode,
@ -684,12 +718,14 @@ let {{
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
double mid = cOp1.fp * cOp2.fp; double mid = cOp1.fp * cOp2.fp;
if ((isinf(cOp1.fp) && cOp2.fp == 0) || if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
(isinf(cOp2.fp) && cOp1.fp == 0)) { (isinf(cOp2.fp) && cOp1.fp == 0)) {
mid = NAN; mid = NAN;
} }
cDest.fp = -cDest.fp + mid; cDest.fp = -cDest.fp + mid;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -701,11 +737,13 @@ let {{
exec_output += PredOpExecute.subst(vnmlsDIop); exec_output += PredOpExecute.subst(vnmlsDIop);
vnmulSCode = ''' vnmulSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
float mid = FpOp1 * FpOp2; float mid = FpOp1 * FpOp2;
if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
mid = NAN; mid = NAN;
} }
FpDest = -mid; FpDest = -mid;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vnmulSIop = InstObjParams("vnmuls", "VnmulS", "VfpRegRegRegOp", vnmulSIop = InstObjParams("vnmuls", "VnmulS", "VfpRegRegRegOp",
{ "code": vnmulSCode, { "code": vnmulSCode,
@ -719,12 +757,14 @@ let {{
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
double mid = cOp1.fp * cOp2.fp; double mid = cOp1.fp * cOp2.fp;
if ((isinf(cOp1.fp) && cOp2.fp == 0) || if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
(isinf(cOp2.fp) && cOp1.fp == 0)) { (isinf(cOp2.fp) && cOp1.fp == 0)) {
mid = NAN; mid = NAN;
} }
cDest.fp = -mid; cDest.fp = -mid;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -736,7 +776,9 @@ let {{
exec_output += PredOpExecute.subst(vnmulDIop); exec_output += PredOpExecute.subst(vnmulDIop);
vcvtUIntFpSCode = ''' vcvtUIntFpSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest = FpOp1.uw; FpDest = FpOp1.uw;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "VfpRegRegOp", vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "VfpRegRegOp",
{ "code": vcvtUIntFpSCode, { "code": vcvtUIntFpSCode,
@ -747,7 +789,9 @@ let {{
vcvtUIntFpDCode = ''' vcvtUIntFpDCode = '''
IntDoubleUnion cDest; IntDoubleUnion cDest;
VfpSavedState state = prepVfpFpscr(Fpscr);
cDest.fp = (uint64_t)FpOp1P0.uw; cDest.fp = (uint64_t)FpOp1P0.uw;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -759,7 +803,9 @@ let {{
exec_output += PredOpExecute.subst(vcvtUIntFpDIop); exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
vcvtSIntFpSCode = ''' vcvtSIntFpSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest = FpOp1.sw; FpDest = FpOp1.sw;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "VfpRegRegOp", vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "VfpRegRegOp",
{ "code": vcvtSIntFpSCode, { "code": vcvtSIntFpSCode,
@ -770,7 +816,9 @@ let {{
vcvtSIntFpDCode = ''' vcvtSIntFpDCode = '''
IntDoubleUnion cDest; IntDoubleUnion cDest;
VfpSavedState state = prepVfpFpscr(Fpscr);
cDest.fp = FpOp1P0.sw; cDest.fp = FpOp1P0.sw;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -782,7 +830,9 @@ let {{
exec_output += PredOpExecute.subst(vcvtSIntFpDIop); exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
vcvtFpUIntSCode = ''' vcvtFpUIntSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest.uw = FpOp1; FpDest.uw = FpOp1;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "VfpRegRegOp", vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "VfpRegRegOp",
{ "code": vcvtFpUIntSCode, { "code": vcvtFpUIntSCode,
@ -794,7 +844,9 @@ let {{
vcvtFpUIntDCode = ''' vcvtFpUIntDCode = '''
IntDoubleUnion cOp1; IntDoubleUnion cOp1;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
uint64_t result = cOp1.fp; uint64_t result = cOp1.fp;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = result; FpDestP0.uw = result;
''' '''
vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "VfpRegRegOp", vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "VfpRegRegOp",
@ -805,7 +857,9 @@ let {{
exec_output += PredOpExecute.subst(vcvtFpUIntDIop); exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
vcvtFpSIntSCode = ''' vcvtFpSIntSCode = '''
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest.sw = FpOp1; FpDest.sw = FpOp1;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "VfpRegRegOp", vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "VfpRegRegOp",
{ "code": vcvtFpSIntSCode, { "code": vcvtFpSIntSCode,
@ -817,7 +871,9 @@ let {{
vcvtFpSIntDCode = ''' vcvtFpSIntDCode = '''
IntDoubleUnion cOp1; IntDoubleUnion cOp1;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
int64_t result = cOp1.fp; int64_t result = cOp1.fp;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = result; FpDestP0.uw = result;
''' '''
vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "VfpRegRegOp", vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "VfpRegRegOp",
@ -829,7 +885,9 @@ let {{
vcvtFpSFpDCode = ''' vcvtFpSFpDCode = '''
IntDoubleUnion cDest; IntDoubleUnion cDest;
VfpSavedState state = prepVfpFpscr(Fpscr);
cDest.fp = FpOp1; cDest.fp = FpOp1;
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = cDest.bits; FpDestP0.uw = cDest.bits;
FpDestP1.uw = cDest.bits >> 32; FpDestP1.uw = cDest.bits >> 32;
''' '''
@ -843,7 +901,9 @@ let {{
vcvtFpDFpSCode = ''' vcvtFpDFpSCode = '''
IntDoubleUnion cOp1; IntDoubleUnion cOp1;
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
VfpSavedState state = prepVfpFpscr(Fpscr);
FpDest = cOp1.fp; FpDest = cOp1.fp;
Fpscr = setVfpFpscr(Fpscr, state);
''' '''
vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "VfpRegRegOp", vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "VfpRegRegOp",
{ "code": vcvtFpDFpSCode, { "code": vcvtFpDFpSCode,