]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
amd64 front/back end stuff needed to support x87 extended-real
authorJulian Seward <jseward@acm.org>
Sat, 26 Mar 2005 21:50:31 +0000 (21:50 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 26 Mar 2005 21:50:31 +0000 (21:50 +0000)
loads/stores.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1099

VEX/priv/guest-amd64/gdefs.h
VEX/priv/guest-amd64/ghelpers.c
VEX/priv/guest-amd64/toIR.c
VEX/priv/host-amd64/isel.c

index 6a6824c4c0f2d8cd06e14da2862291aae576d634..3e21bc1f8d143055e22577dfe9f2d98663eccfa1 100644 (file)
@@ -123,9 +123,9 @@ extern UInt  amd64g_calculate_sse_pmovmskb ( ULong w64hi, ULong w64lo );
 
 /* --- DIRTY HELPERS --- */
 
-//extern ULong amd64g_loadF80le  ( ULong/*addr*/ );
+extern ULong amd64g_loadF80le  ( ULong/*addr*/ );
 
-//extern void  amd64g_storeF80le ( ULong/*addr*/, ULong );
+extern void  amd64g_storeF80le ( ULong/*addr*/, ULong/*data*/ );
 
 extern void amd64g_dirtyhelper_CPUID ( VexGuestAMD64State* st );
 
index 940e481990556e7eb28134128881c2c12a4096ff..3cb23604f0e64b8071508c8f2c21f0be192ca040 100644 (file)
@@ -41,7 +41,7 @@
 
 #include "main/vex_util.h"
 #include "guest-amd64/gdefs.h"
-
+#include "guest-generic/g_generic_x87.h"
 
 
 /* This file contains helper functions for amd64 guest code.
@@ -1185,6 +1185,23 @@ void amd64g_dirtyhelper_FINIT ( VexGuestAMD64State* gst )
 }
 
 
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (reads guest memory) */
+ULong amd64g_loadF80le ( ULong addrU )
+{
+   ULong f64;
+   convert_f80le_to_f64le ( (UChar*)ULong_to_Ptr(addrU), (UChar*)&f64 );
+   return f64;
+}
+
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (writes guest memory) */
+void amd64g_storeF80le ( ULong addrU, ULong f64 )
+{
+   convert_f64le_to_f80le( (UChar*)&f64, (UChar*)ULong_to_Ptr(addrU) );
+}
+
+
 /*---------------------------------------------------------------*/
 /*--- Misc integer helpers, including rotates and CPUID.      ---*/
 /*---------------------------------------------------------------*/
index d6034816591b3184319d2e7e0e363d5e2fd1d2d7..bb0b22f0bf8fd7b8b1e90ebc5b5a686d440ce3e4 100644 (file)
@@ -5092,57 +5092,59 @@ ULong dis_FPU ( /*OUT*/Bool* decode_ok,
                fp_pop();
                break;
 
-//..             case 5: { /* FLD extended-real */
-//..                /* Uses dirty helper: 
-//..                      ULong loadF80le ( VexGuestX86State*, UInt )
-//..                   addr holds the address.  First, do a dirty call to
-//..                   get hold of the data. */
-//..                IRTemp   val  = newTemp(Ity_I64);
-//..                IRExpr** args = mkIRExprVec_1 ( mkexpr(addr) );
-//.. 
-//..                IRDirty* d = unsafeIRDirty_1_N ( 
-//..                                val, 
-//..                                0/*regparms*/, 
-//..                                "x86g_loadF80le", &x86g_loadF80le, 
-//..                                args 
-//..                             );
-//..                /* declare that we're reading memory */
-//..                d->mFx   = Ifx_Read;
-//..                d->mAddr = mkexpr(addr);
-//..                d->mSize = 10;
-//.. 
-//..                /* execute the dirty call, dumping the result in val. */
-//..                stmt( IRStmt_Dirty(d) );
-//..                fp_push();
-//..                put_ST(0, unop(Iop_ReinterpI64asF64, mkexpr(val)));
-//.. 
-//..                DIP("fldt %s\n", dis_buf);
-//..                break;
-//..             }
-//.. 
-//..             case 7: { /* FSTP extended-real */
-//..                /* Uses dirty helper: void x86g_storeF80le ( UInt, ULong ) */
-//..                IRExpr** args 
-//..                   = mkIRExprVec_2( mkexpr(addr), 
-//..                                    unop(Iop_ReinterpF64asI64, get_ST(0)) );
-//.. 
-//..                IRDirty* d = unsafeIRDirty_0_N ( 
-//..                                0/*regparms*/, 
-//..                                "x86g_storeF80le", &x86g_storeF80le,
-//..                                args 
-//..                             );
-//..                /* declare we're writing memory */
-//..                d->mFx   = Ifx_Write;
-//..                d->mAddr = mkexpr(addr);
-//..                d->mSize = 10;
-//.. 
-//..                /* execute the dirty call. */
-//..                stmt( IRStmt_Dirty(d) );
-//..                fp_pop();
-//.. 
-//..                DIP("fstpt\n %s", dis_buf);
-//..                break;
-//..             }
+            case 5: { /* FLD extended-real */
+               /* Uses dirty helper: 
+                     ULong amd64g_loadF80le ( ULong )
+                  addr holds the address.  First, do a dirty call to
+                  get hold of the data. */
+               IRTemp   val  = newTemp(Ity_I64);
+               IRExpr** args = mkIRExprVec_1 ( mkexpr(addr) );
+
+               IRDirty* d = unsafeIRDirty_1_N ( 
+                               val, 
+                               0/*regparms*/, 
+                               "amd64g_loadF80le", &amd64g_loadF80le, 
+                               args 
+                            );
+               /* declare that we're reading memory */
+               d->mFx   = Ifx_Read;
+               d->mAddr = mkexpr(addr);
+               d->mSize = 10;
+
+               /* execute the dirty call, dumping the result in val. */
+               stmt( IRStmt_Dirty(d) );
+               fp_push();
+               put_ST(0, unop(Iop_ReinterpI64asF64, mkexpr(val)));
+
+               DIP("fldt %s\n", dis_buf);
+               break;
+            }
+
+            case 7: { /* FSTP extended-real */
+               /* Uses dirty helper: 
+                     void amd64g_storeF80le ( ULong addr, ULong data ) 
+               */
+               IRExpr** args 
+                  = mkIRExprVec_2( mkexpr(addr), 
+                                   unop(Iop_ReinterpF64asI64, get_ST(0)) );
+
+               IRDirty* d = unsafeIRDirty_0_N ( 
+                               0/*regparms*/, 
+                               "amd64g_storeF80le", &amd64g_storeF80le,
+                               args 
+                            );
+               /* declare we're writing memory */
+               d->mFx   = Ifx_Write;
+               d->mAddr = mkexpr(addr);
+               d->mSize = 10;
+
+               /* execute the dirty call. */
+               stmt( IRStmt_Dirty(d) );
+               fp_pop();
+
+               DIP("fstpt\n %s", dis_buf);
+               break;
+            }
 
             default:
                vex_printf("unhandled opc_aux = 0x%2x\n", gregLO3ofRM(modrm));
@@ -5164,17 +5166,17 @@ ULong dis_FPU ( /*OUT*/Bool* decode_ok,
 //..                                          mk_x86g_calculate_condition(X86CondNB)), 
 //..                                     get_ST(0), get_ST(r_src)) );
 //..                break;
-//.. 
-//..             case 0xC8 ... 0xCF: /* FCMOVNE(NZ) ST(i), ST(0) */
-//..                r_src = (UInt)modrm - 0xC8;
-//..                DIP("fcmovnz %%st(%d), %%st(0)\n", r_src);
-//..                put_ST_UNCHECKED(0, 
-//..                                 IRExpr_Mux0X( 
-//..                                     unop(Iop_1Uto8,
-//..                                          mk_x86g_calculate_condition(X86CondNZ)), 
-//..                                     get_ST(0), get_ST(r_src)) );
-//..                break;
-//.. 
+
+            case 0xC8 ... 0xCF: /* FCMOVNE(NZ) ST(i), ST(0) */
+               r_src = (UInt)modrm - 0xC8;
+               DIP("fcmovnz %%st(%d), %%st(0)\n", r_src);
+               put_ST_UNCHECKED(0, 
+                                IRExpr_Mux0X( 
+                                    unop(Iop_1Uto8,
+                                         mk_amd64g_calculate_condition(AMD64CondNZ)), 
+                                    get_ST(0), get_ST(r_src)) );
+               break;
+
 //..             case 0xD0 ... 0xD7: /* FCMOVNBE ST(i), ST(0) */
 //..                r_src = (UInt)modrm - 0xD0;
 //..                DIP("fcmovnbe %%st(%d), %%st(0)\n", r_src);
@@ -5743,11 +5745,11 @@ ULong dis_FPU ( /*OUT*/Bool* decode_ok,
 //..                              binop(Iop_And32, get_C3210(), mkU32(0x4700))
 //..                )));
 //..                break;
-//.. 
-//..             case 0xE8 ... 0xEF: /* FUCOMIP %st(0),%st(?) */
-//..                fp_do_ucomi_ST0_STi( (UInt)modrm - 0xE8, True );
-//..                break;
-//.. 
+
+            case 0xE8 ... 0xEF: /* FUCOMIP %st(0),%st(?) */
+               fp_do_ucomi_ST0_STi( (UInt)modrm - 0xE8, True );
+               break;
+
 //..             case 0xF0 ... 0xF7: /* FCOMIP %st(0),%st(?) */
 //..                /* not really right since COMIP != UCOMIP */
 //..                fp_do_ucomi_ST0_STi( (UInt)modrm - 0xF0, True );
index 3678be8e2d01b3aef3d3e9b4c09468ede0b89d55..c231f6d300f57630ef82e007e1b5a71769e5b367 100644 (file)
@@ -1343,6 +1343,21 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
             return dst;
          }
 
+         /* ReinterpF64asI64(e) */
+         /* Given an IEEE754 double, produce an I64 with the same bit
+            pattern. */
+         case Iop_ReinterpF64asI64: {
+            AMD64AMode* m8_rsp = AMD64AMode_IR(-8, hregAMD64_RSP());
+            HReg        dst    = newVRegI(env);
+            HReg        src    = iselDblExpr(env, e->Iex.Unop.arg);
+            /* paranoia */
+            set_SSE_rounding_default(env);
+            addInstr(env, AMD64Instr_SseLdSt(False/*store*/, 8, src, m8_rsp));
+            addInstr(env, AMD64Instr_Alu64R(
+                             Aalu_MOV, AMD64RMI_Mem(m8_rsp), dst));
+            return dst;
+         }
+
          case Iop_16to8:
          case Iop_32to8:
          case Iop_32to16:
@@ -2473,35 +2488,6 @@ static void iselInt128Expr_wrk ( HReg* rHi, HReg* rLo,
 //..             return;
 //..          }
 //.. 
-//..          /* ReinterpF64asI64(e) */
-//..          /* Given an IEEE754 double, produce an I64 with the same bit
-//..             pattern. */
-//..          case Iop_ReinterpF64asI64: {
-//..             HReg rf   = iselDblExpr(env, e->Iex.Unop.arg);
-//..             HReg tLo  = newVRegI(env);
-//..             HReg tHi  = newVRegI(env);
-//..             X86AMode* zero_esp = X86AMode_IR(0, hregX86_ESP());
-//..             X86AMode* four_esp = X86AMode_IR(4, hregX86_ESP());
-//..             /* paranoia */
-//..             set_FPU_rounding_default(env);
-//..             /* subl $8, %esp */
-//..             sub_from_esp(env, 8);
-//..             /* gstD %rf, 0(%esp) */
-//..             addInstr(env,
-//..                      X86Instr_FpLdSt(False/*store*/, 8, rf, zero_esp));
-//..             /* movl 0(%esp), %tLo */
-//..             addInstr(env, 
-//..                      X86Instr_Alu32R(Xalu_MOV, X86RMI_Mem(zero_esp), tLo));
-//..             /* movl 4(%esp), %tHi */
-//..             addInstr(env, 
-//..                      X86Instr_Alu32R(Xalu_MOV, X86RMI_Mem(four_esp), tHi));
-//..             /* addl $8, %esp */
-//..             add_to_esp(env, 8);
-//..             *rHi = tHi;
-//..             *rLo = tLo;
-//..             return;
-//..          }
-//.. 
 //..          case Iop_CmpNEZ32x2:
 //..             fn = (HWord)h_generic_calc_CmpNEZ32x2; goto unish;
 //..          case Iop_CmpNEZ16x4:
@@ -2853,22 +2839,18 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e )
 //..             add_to_esp(env, 4);
 //..             return dst;
 //..          }
-//..          case Iop_ReinterpI64asF64: {
-//..             /* Given an I64, produce an IEEE754 double with the same
-//..                bit pattern. */
-//..             HReg dst = newVRegF(env);
-//..             HReg rHi, rLo;
-//..             iselInt64Expr( &rHi, &rLo, env, e->Iex.Unop.arg);
-//..             /* paranoia */
-//..             set_FPU_rounding_default(env);
-//..             addInstr(env, X86Instr_Push(X86RMI_Reg(rHi)));
-//..             addInstr(env, X86Instr_Push(X86RMI_Reg(rLo)));
-//..             addInstr(env, X86Instr_FpLdSt(
-//..                              True/*load*/, 8, dst, 
-//..                              X86AMode_IR(0, hregX86_ESP())));
-//..             add_to_esp(env, 8);
-//..             return dst;
-//..          }
+         case Iop_ReinterpI64asF64: {
+            /* Given an I64, produce an IEEE754 double with the same
+               bit pattern. */
+            AMD64AMode* m8_rsp = AMD64AMode_IR(-8, hregAMD64_RSP());
+            HReg        dst    = newVRegV(env);
+            AMD64RI*    src    = iselIntExpr_RI(env, e->Iex.Unop.arg);
+            /* paranoia */
+            set_SSE_rounding_default(env);
+            addInstr(env, AMD64Instr_Alu64M(Aalu_MOV, src, m8_rsp));
+            addInstr(env, AMD64Instr_SseLdSt(True/*load*/, 8, dst, m8_rsp));
+            return dst;
+         }
          case Iop_F32toF64: {
             HReg f32;
             HReg f64 = newVRegV(env);