ARM: Implement the version of VCVT float to int that rounds towards zero.
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/isa/formats/fp.isa
src/arch/arm/isa/insts/fp.isa

index 3d40caf9e88d47c19f36253b518c3f90ed17de14..2b999f751a1c28eceb533686464d0525eb43180a 100644 (file)
@@ -725,20 +725,40 @@ let {{
                     }
                 }
               case 0xc:
-                if (single) {
-                    return new VcvtFpUIntS(machInst, vd, vm);
+                if (bits(machInst, 7) == 0) {
+                    if (single) {
+                        return new VcvtFpUIntSR(machInst, vd, vm);
+                    } else {
+                        vd = (IntRegIndex)(bits(machInst, 22) |
+                                (bits(machInst, 15, 12) << 1));
+                        return new VcvtFpUIntDR(machInst, vd, vm);
+                    }
                 } else {
-                    vd = (IntRegIndex)(bits(machInst, 22) |
-                            (bits(machInst, 15, 12) << 1));
-                    return new VcvtFpUIntD(machInst, vd, vm);
+                    if (single) {
+                        return new VcvtFpUIntS(machInst, vd, vm);
+                    } else {
+                        vd = (IntRegIndex)(bits(machInst, 22) |
+                                (bits(machInst, 15, 12) << 1));
+                        return new VcvtFpUIntD(machInst, vd, vm);
+                    }
                 }
               case 0xd:
-                if (single) {
-                    return new VcvtFpSIntS(machInst, vd, vm);
+                if (bits(machInst, 7) == 0) {
+                    if (single) {
+                        return new VcvtFpSIntSR(machInst, vd, vm);
+                    } else {
+                        vd = (IntRegIndex)(bits(machInst, 22) |
+                                (bits(machInst, 15, 12) << 1));
+                        return new VcvtFpSIntDR(machInst, vd, vm);
+                    }
                 } else {
-                    vd = (IntRegIndex)(bits(machInst, 22) |
-                            (bits(machInst, 15, 12) << 1));
-                    return new VcvtFpSIntD(machInst, vd, vm);
+                    if (single) {
+                        return new VcvtFpSIntS(machInst, vd, vm);
+                    } else {
+                        vd = (IntRegIndex)(bits(machInst, 22) |
+                                (bits(machInst, 15, 12) << 1));
+                        return new VcvtFpSIntD(machInst, vd, vm);
+                    }
                 }
               case 0xe:
                 {
index db1c5bf6b848c172548c5aa5e112aefbafdc087f..93c5cf8b480dc9f06ff90524b91c63151249c821 100644 (file)
@@ -829,8 +829,63 @@ let {{
     decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpDIop);
     exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
 
+    vcvtFpUIntSRCode = '''
+        VfpSavedState state = prepVfpFpscr(Fpscr);
+        FpDest.uw = FpOp1;
+        Fpscr = setVfpFpscr(Fpscr, state);
+    '''
+    vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "VfpRegRegOp",
+                                     { "code": vcvtFpUIntSRCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
+    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
+    exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
+
+    vcvtFpUIntDRCode = '''
+        IntDoubleUnion cOp1;
+        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
+        VfpSavedState state = prepVfpFpscr(Fpscr);
+        uint64_t result = cOp1.fp;
+        Fpscr = setVfpFpscr(Fpscr, state);
+        FpDestP0.uw = result;
+    '''
+    vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "VfpRegRegOp",
+                                     { "code": vcvtFpUIntDRCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
+    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
+    exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
+
+    vcvtFpSIntSRCode = '''
+        VfpSavedState state = prepVfpFpscr(Fpscr);
+        FpDest.sw = FpOp1;
+        Fpscr = setVfpFpscr(Fpscr, state);
+    '''
+    vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "VfpRegRegOp",
+                                     { "code": vcvtFpSIntSRCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
+    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
+    exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
+
+    vcvtFpSIntDRCode = '''
+        IntDoubleUnion cOp1;
+        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
+        VfpSavedState state = prepVfpFpscr(Fpscr);
+        int64_t result = cOp1.fp;
+        Fpscr = setVfpFpscr(Fpscr, state);
+        FpDestP0.uw = result;
+    '''
+    vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "VfpRegRegOp",
+                                     { "code": vcvtFpSIntDRCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
+    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
+    exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
+
     vcvtFpUIntSCode = '''
         VfpSavedState state = prepVfpFpscr(Fpscr);
+        fesetround(FeRoundZero);
         FpDest.uw = FpOp1;
         Fpscr = setVfpFpscr(Fpscr, state);
     '''
@@ -845,6 +900,7 @@ let {{
         IntDoubleUnion cOp1;
         cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
         VfpSavedState state = prepVfpFpscr(Fpscr);
+        fesetround(FeRoundZero);
         uint64_t result = cOp1.fp;
         Fpscr = setVfpFpscr(Fpscr, state);
         FpDestP0.uw = result;
@@ -858,6 +914,7 @@ let {{
 
     vcvtFpSIntSCode = '''
         VfpSavedState state = prepVfpFpscr(Fpscr);
+        fesetround(FeRoundZero);
         FpDest.sw = FpOp1;
         Fpscr = setVfpFpscr(Fpscr, state);
     '''
@@ -872,6 +929,7 @@ let {{
         IntDoubleUnion cOp1;
         cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
         VfpSavedState state = prepVfpFpscr(Fpscr);
+        fesetround(FeRoundZero);
         int64_t result = cOp1.fp;
         Fpscr = setVfpFpscr(Fpscr, state);
         FpDestP0.uw = result;
@@ -1062,7 +1120,7 @@ let {{
 
     vcvtSFixedFpSCode = '''
         VfpSavedState state = prepVfpFpscr(Fpscr);
-        FpDest = vfpSFixedToFpS(FpOp1.sw, true, imm);
+        FpDest = vfpSFixedToFpS(FpOp1.sw, false, imm);
         Fpscr = setVfpFpscr(Fpscr, state);
     '''
     vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "VfpRegRegImmOp",
@@ -1076,7 +1134,7 @@ let {{
         IntDoubleUnion cDest;
         uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
         VfpSavedState state = prepVfpFpscr(Fpscr);
-        cDest.fp = vfpSFixedToFpD(mid, true, imm);
+        cDest.fp = vfpSFixedToFpD(mid, false, imm);
         Fpscr = setVfpFpscr(Fpscr, state);
         FpDestP0.uw = cDest.bits;
         FpDestP1.uw = cDest.bits >> 32;