summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/insts/vfp.hh19
-rw-r--r--src/arch/arm/isa/insts/fp.isa8
2 files changed, 19 insertions, 8 deletions
diff --git a/src/arch/arm/insts/vfp.hh b/src/arch/arm/insts/vfp.hh
index 11ae8ed96..6ded88670 100644
--- a/src/arch/arm/insts/vfp.hh
+++ b/src/arch/arm/insts/vfp.hh
@@ -309,11 +309,17 @@ fixFpDFpSDest(FPSCR fpscr, double val)
}
static inline uint64_t
-vfpFpSToFixed(float val, bool isSigned, bool half, uint8_t imm)
+vfpFpSToFixed(float val, bool isSigned, bool half,
+ uint8_t imm, bool rzero = true)
{
- fesetround(FeRoundZero);
+ int rmode = fegetround();
+ fesetround(FeRoundNearest);
val = val * powf(2.0, imm);
__asm__ __volatile__("" : "=m" (val) : "m" (val));
+ if (rzero)
+ fesetround(FeRoundZero);
+ else
+ fesetround(rmode);
feclearexcept(FeAllExceptions);
__asm__ __volatile__("" : "=m" (val) : "m" (val));
float origVal = val;
@@ -410,12 +416,17 @@ vfpSFixedToFpS(FPSCR fpscr, int32_t val, bool half, uint8_t imm)
}
static inline uint64_t
-vfpFpDToFixed(double val, bool isSigned, bool half, uint8_t imm)
+vfpFpDToFixed(double val, bool isSigned, bool half,
+ uint8_t imm, bool rzero = true)
{
+ int rmode = fegetround();
fesetround(FeRoundNearest);
val = val * pow(2.0, imm);
__asm__ __volatile__("" : "=m" (val) : "m" (val));
- fesetround(FeRoundZero);
+ if (rzero)
+ fesetround(FeRoundZero);
+ else
+ fesetround(rmode);
feclearexcept(FeAllExceptions);
__asm__ __volatile__("" : "=m" (val) : "m" (val));
double origVal = val;
diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa
index 33a85b04e..045f516ce 100644
--- a/src/arch/arm/isa/insts/fp.isa
+++ b/src/arch/arm/isa/insts/fp.isa
@@ -933,7 +933,7 @@ let {{
vfpFlushToZero(Fpscr, FpOp1);
VfpSavedState state = prepVfpFpscr(Fpscr);
__asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
- FpDest.uw = vfpFpSToFixed(FpOp1, false, false, 0);
+ FpDest.uw = vfpFpSToFixed(FpOp1, false, false, 0, false);
__asm__ __volatile__("" :: "m" (FpDest.uw));
Fpscr = setVfpFpscr(Fpscr, state);
'''
@@ -950,7 +950,7 @@ let {{
vfpFlushToZero(Fpscr, cOp1.fp);
VfpSavedState state = prepVfpFpscr(Fpscr);
__asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
- uint64_t result = vfpFpDToFixed(cOp1.fp, false, false, 0);
+ uint64_t result = vfpFpDToFixed(cOp1.fp, false, false, 0, false);
__asm__ __volatile__("" :: "m" (result));
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = result;
@@ -966,7 +966,7 @@ let {{
vfpFlushToZero(Fpscr, FpOp1);
VfpSavedState state = prepVfpFpscr(Fpscr);
__asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
- FpDest.sw = vfpFpSToFixed(FpOp1, true, false, 0);
+ FpDest.sw = vfpFpSToFixed(FpOp1, true, false, 0, false);
__asm__ __volatile__("" :: "m" (FpDest.sw));
Fpscr = setVfpFpscr(Fpscr, state);
'''
@@ -983,7 +983,7 @@ let {{
vfpFlushToZero(Fpscr, cOp1.fp);
VfpSavedState state = prepVfpFpscr(Fpscr);
__asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
- int64_t result = vfpFpDToFixed(cOp1.fp, true, false, 0);
+ int64_t result = vfpFpDToFixed(cOp1.fp, true, false, 0, false);
__asm__ __volatile__("" :: "m" (result));
Fpscr = setVfpFpscr(Fpscr, state);
FpDestP0.uw = result;