ARM: Implement vcvt between int and fp. Ignore rounding.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:14 +0000 (12:58 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 2 Jun 2010 17:58:14 +0000 (12:58 -0500)
src/arch/arm/isa/formats/fp.isa
src/arch/arm/isa/insts/fp.isa

index a1c11d1d19cdc5b3639f3204a5615268b69e94a9..47703a7a045b1ff4d15c3449976e58a656f89d7b 100644 (file)
@@ -621,16 +621,43 @@ let {{
                 }
                 break;
               case 0x8:
-                // Between FP and int.
-                return new WarnUnimplemented("vcvt, vcvtr", machInst);
+                if (bits(machInst, 7) == 0) {
+                    if (single) {
+                        return new VcvtUIntFpS(machInst, vd, vm);
+                    } else {
+                        vm = (IntRegIndex)(bits(machInst, 5) |
+                                (bits(machInst, 3, 0) << 1));
+                        return new VcvtUIntFpD(machInst, vd, vm);
+                    }
+                } else {
+                    if (single) {
+                        return new VcvtSIntFpS(machInst, vd, vm);
+                    } else {
+                        vm = (IntRegIndex)(bits(machInst, 5) |
+                                (bits(machInst, 3, 0) << 1));
+                        return new VcvtSIntFpD(machInst, vd, vm);
+                    }
+                }
               case 0xa:
               case 0xb:
                 // Between FP and fixed point.
                 return new WarnUnimplemented("vcvt", machInst);
               case 0xc:
+                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:
-                // Between FP and int.
-                return new WarnUnimplemented("vcvt, vcvtr", machInst);
+                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:
               case 0xf:
                 // Between FP and fixed point.
index d40b001769775faf1fb5520b8e0e1189f93fd3a2..35d0405e94088a858ae8cb1f42315c6ad4554af9 100644 (file)
@@ -586,4 +586,96 @@ let {{
     header_output += RegRegRegOpDeclare.subst(vnmulDIop);
     decoder_output += RegRegRegOpConstructor.subst(vnmulDIop);
     exec_output += PredOpExecute.subst(vnmulDIop);
+
+    vcvtUIntFpSCode = '''
+        FpDest = FpOp1.uw;
+    '''
+    vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "RegRegOp",
+                                     { "code": vcvtUIntFpSCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtUIntFpSIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtUIntFpSIop);
+    exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
+
+    vcvtUIntFpDCode = '''
+        IntDoubleUnion cDest;
+        cDest.fp = (uint64_t)FpOp1P0.uw;
+        FpDestP0.uw = cDest.bits;
+        FpDestP1.uw = cDest.bits >> 32;
+    '''
+    vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "RegRegOp",
+                                     { "code": vcvtUIntFpDCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtUIntFpDIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtUIntFpDIop);
+    exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
+
+    vcvtSIntFpSCode = '''
+        FpDest = FpOp1.sw;
+    '''
+    vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "RegRegOp",
+                                     { "code": vcvtSIntFpSCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtSIntFpSIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtSIntFpSIop);
+    exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
+
+    vcvtSIntFpDCode = '''
+        IntDoubleUnion cDest;
+        cDest.fp = FpOp1P0.sw;
+        FpDestP0.uw = cDest.bits;
+        FpDestP1.uw = cDest.bits >> 32;
+    '''
+    vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "RegRegOp",
+                                     { "code": vcvtSIntFpDCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtSIntFpDIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtSIntFpDIop);
+    exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
+
+    vcvtFpUIntSCode = '''
+        FpDest.uw = FpOp1;
+    '''
+    vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "RegRegOp",
+                                     { "code": vcvtFpUIntSCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtFpUIntSIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtFpUIntSIop);
+    exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
+
+    vcvtFpUIntDCode = '''
+        IntDoubleUnion cOp1;
+        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
+        uint64_t result = cOp1.fp;
+        FpDestP0.uw = result;
+    '''
+    vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "RegRegOp",
+                                     { "code": vcvtFpUIntDCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtFpUIntDIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtFpUIntDIop);
+    exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
+
+    vcvtFpSIntSCode = '''
+        FpDest.sw = FpOp1;
+    '''
+    vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "RegRegOp",
+                                     { "code": vcvtFpSIntSCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtFpSIntSIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtFpSIntSIop);
+    exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
+
+    vcvtFpSIntDCode = '''
+        IntDoubleUnion cOp1;
+        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
+        int64_t result = cOp1.fp;
+        FpDestP0.uw = result;
+    '''
+    vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "RegRegOp",
+                                     { "code": vcvtFpSIntDCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtFpSIntDIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtFpSIntDIop);
+    exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
 }};