ARM: Implement VCVT between double and single width FP.
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 47703a7a045b1ff4d15c3449976e58a656f89d7b..e92757096df0f0a5a72c33b5eb14e449c87338f7 100644 (file)
@@ -616,8 +616,15 @@ let {{
                 return new WarnUnimplemented("vcmp, vcmpe", machInst);
               case 0x7:
                 if (opc3 == 0x3) {
-                    // Between double and single precision.
-                    return new WarnUnimplemented("vcvt", machInst);
+                    if (single) {
+                        vm = (IntRegIndex)(bits(machInst, 5) |
+                                (bits(machInst, 3, 0) << 1));
+                        return new VcvtFpSFpD(machInst, vd, vm);
+                    } else {
+                        vd = (IntRegIndex)(bits(machInst, 22) |
+                                (bits(machInst, 15, 12) << 1));
+                        return new VcvtFpDFpS(machInst, vd, vm);
+                    }
                 }
                 break;
               case 0x8:
index 35d0405e94088a858ae8cb1f42315c6ad4554af9..9969e67118a8051610134239ac65a86990a7b489 100644 (file)
@@ -678,4 +678,29 @@ let {{
     header_output += RegRegOpDeclare.subst(vcvtFpSIntDIop);
     decoder_output += RegRegOpConstructor.subst(vcvtFpSIntDIop);
     exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
+
+    vcvtFpSFpDCode = '''
+        IntDoubleUnion cDest;
+        cDest.fp = FpOp1;
+        FpDestP0.uw = cDest.bits;
+        FpDestP1.uw = cDest.bits >> 32;
+    '''
+    vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "RegRegOp",
+                                     { "code": vcvtFpSFpDCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtFpSFpDIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtFpSFpDIop);
+    exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
+
+    vcvtFpDFpSCode = '''
+        IntDoubleUnion cOp1;
+        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
+        FpDest = cOp1.fp;
+    '''
+    vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "RegRegOp",
+                                     { "code": vcvtFpDFpSCode,
+                                       "predicate_test": predicateTest }, [])
+    header_output += RegRegOpDeclare.subst(vcvtFpDFpSIop);
+    decoder_output += RegRegOpConstructor.subst(vcvtFpDFpSIop);
+    exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
 }};