]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Various more x86 FP cases.
authorJulian Seward <jseward@acm.org>
Thu, 9 Sep 2004 22:43:51 +0000 (22:43 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 9 Sep 2004 22:43:51 +0000 (22:43 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@248

VEX/priv/guest-x86/toIR.c

index 1b8fb64cb47116533cf9c7da13b9fb88b01aa5f6..b11605f86af28be15df0d1c76ef4d732e261bd07 100644 (file)
@@ -3283,7 +3283,7 @@ static void fp_pop ( void )
    and describe FP instructions. 
 */
 
-/* ST(0) = ST(0) `op` mem64(addr)       (when dbl==True) 
+/* ST(0) = ST(0) `op` mem64/32(addr)
    Need to check ST(0)'s tag on read, but not on write.
 */
 static
@@ -3292,10 +3292,41 @@ void fp_do_op_mem_ST_0 ( IRTemp addr, UChar* op_txt, UChar* dis_buf,
 {
    DIP("f%s%c %s", op_txt, dbl?'l':'s', dis_buf);
    if (dbl) {
-      put_ST_UNCHECKED(0, binop(op, get_ST(0), loadLE(Ity_F64,mkexpr(addr))));
+      put_ST_UNCHECKED(0, 
+         binop( op, 
+                get_ST(0), 
+                loadLE(Ity_F64,mkexpr(addr))
+         ));
    } else {
-      put_ST_UNCHECKED(0, binop(op, get_ST(0), 
-                          unop(Iop_F32toF64,loadLE(Ity_F32,mkexpr(addr)))));
+      put_ST_UNCHECKED(0, 
+         binop( op, 
+                get_ST(0), 
+                unop(Iop_F32toF64, loadLE(Ity_F32,mkexpr(addr)))
+         ));
+   }
+}
+
+
+/* ST(0) = mem64/32(addr) `op` ST(0)
+   Need to check ST(0)'s tag on read, but not on write.
+*/
+static
+void fp_do_oprev_mem_ST_0 ( IRTemp addr, UChar* op_txt, UChar* dis_buf, 
+                         IROp op, Bool dbl )
+{
+   DIP("f%s%c %s", op_txt, dbl?'l':'s', dis_buf);
+   if (dbl) {
+      put_ST_UNCHECKED(0, 
+         binop( op, 
+                loadLE(Ity_F64,mkexpr(addr)),
+                get_ST(0)
+         ));
+   } else {
+      put_ST_UNCHECKED(0, 
+         binop( op, 
+                unop(Iop_F32toF64, loadLE(Ity_F32,mkexpr(addr))),
+                get_ST(0)
+         ));
    }
 }
 
@@ -3358,6 +3389,10 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
 
          switch (gregOfRM(modrm)) {
 
+            case 0: /* FADD single-real */
+               fp_do_op_mem_ST_0 ( addr, "add", dis_buf, Iop_AddF64, False );
+               break;
+
             case 1: /* FMUL single-real */
                fp_do_op_mem_ST_0 ( addr, "mul", dis_buf, Iop_MulF64, False );
                break;
@@ -3379,10 +3414,22 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                fp_do_op_ST_ST ( "add", Iop_AddF64, modrm - 0xC0, 0, False );
                break;
 
+            case 0xC8 ... 0xCF: /* FMUL %st(?),%st(0) */
+               fp_do_op_ST_ST ( "mul", Iop_MulF64, modrm - 0xC8, 0, False );
+               break;
+
             case 0xE0 ... 0xE7: /* FSUB %st(?),%st(0) */
                fp_do_op_ST_ST ( "sub", Iop_SubF64, modrm - 0xE0, 0, False );
                break;
 
+            case 0xF0 ... 0xF7: /* FDIV %st(?),%st(0) */
+               fp_do_op_ST_ST ( "div", Iop_DivF64, modrm - 0xF0, 0, False );
+               break;
+
+            case 0xF8 ... 0xFF: /* FDIVR %st(?),%st(0) */
+               fp_do_oprev_ST_ST ( "divr", Iop_DivF64, modrm - 0xF8, 0, False );
+               break;
+
             default:
                goto decode_fail;
          }
@@ -3557,6 +3604,15 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
          delta++;
          switch (modrm) {
 
+            case 0xC8 ... 0xCF: /* FCMOVE(Z) ST(i), ST(0) */
+               r_src = (UInt)modrm - 0xC8;
+              DIP("fcmovz %%st(%d), %%st(0)", r_src);
+              put_ST_UNCHECKED(0, 
+                                IRExpr_Mux0X( 
+                                    unop(Iop_1Uto8,calculate_condition(CondZ)), 
+                                    get_ST(0), get_ST(r_src)) );
+               break;
+
             case 0xE9: /* FUCOMPP %st(0),%st(1) */
                DIP("fucompp %%st(0),%%st(1)\n");
                put_C320( binop(Iop_Shl32, 
@@ -3640,6 +3696,10 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                fp_do_op_mem_ST_0 ( addr, "sub", dis_buf, Iop_SubF64, True );
                break;
 
+            case 5: /* FSUBR double-real */
+               fp_do_oprev_mem_ST_0 ( addr, "subr", dis_buf, Iop_SubF64, True );
+               break;
+
             case 6: /* FDIV double-real */
                fp_do_op_mem_ST_0 ( addr, "div", dis_buf, Iop_DivF64, True );
                break;
@@ -3655,6 +3715,10 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
          delta++;
          switch (modrm) {
 
+            case 0xC0 ... 0xC7: /* FADD %st(0),%st(?) */
+               fp_do_op_ST_ST ( "add", Iop_AddF64, 0, modrm - 0xC0, False );
+               break;
+
             case 0xC8 ... 0xCF: /* FMUL %st(0),%st(?) */
                fp_do_op_ST_ST ( "mul", Iop_MulF64, 0, modrm - 0xC8, False );
                break;
@@ -3770,6 +3834,10 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                fp_do_oprev_ST_ST ( "subr", Iop_SubF64, 0,  modrm - 0xE0, True );
                break;
 
+            case 0xE8 ... 0xEF: /* FSUBP %st(0),%st(?) */
+               fp_do_op_ST_ST ( "sub", Iop_SubF64, 0,  modrm - 0xE8, True );
+               break;
+
             case 0xF0 ... 0xF7: /* FDIVRP %st(0),%st(?) */
                fp_do_oprev_ST_ST ( "divr", Iop_DivF64, 0, modrm - 0xF0, True );
                break;