ARM: Fix vcvtr so that it uses the rounding mode in the FPSCR.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:15 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:15 +0000 (12:58 -0500)
src/arch/arm/insts/vfp.hh
src/arch/arm/isa/insts/fp.isa

index 11ae8ed96a3130de2f92cea3dc7f698244d517a7..6ded88670b09727cf6e0226521644e6a615e2157 100644 (file)
@@ -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;
index 33a85b04e7a88a056f14b1841d8e6c190d14c834..045f516ceeb2ede3b6e38cc8853ef5a42d7bb951 100644 (file)
@@ -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;