ARM: Add code to extract and record VFP exceptions.
This commit is contained in:
parent
e478df35f5
commit
86a1093992
2 changed files with 135 additions and 0 deletions
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue