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;