]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Instead of denoting helper call targets by their names, add a new type
authorJulian Seward <jseward@acm.org>
Sat, 30 Oct 2004 19:03:02 +0000 (19:03 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 30 Oct 2004 19:03:02 +0000 (19:03 +0000)
IRCallee to carry the name (for printing), the actual address, and the
"regparm" number if relevant.  This gets rid of the need to pass
around helper-lookup callbacks all over the place, and also lays the
groundwork for a generic "regparm" mechanism for the back end.

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

VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c
VEX/priv/host-x86/hdefs.h
VEX/priv/host-x86/isel.c
VEX/priv/ir/irdefs.c
VEX/priv/ir/iropt.c
VEX/priv/main/vex_main.c
VEX/pub/libvex.h
VEX/pub/libvex_ir.h

index ab43597f69fa09bf285695dfb6f5685922bde423..f4d714933fc38089ef98d08885803c6c0385eb97 100644 (file)
@@ -26,11 +26,6 @@ IRBB* bbToIR_X86Instr ( UChar* x86code,
                         Bool   (*byte_accessible)(Addr64),
                         Bool   host_bigendian );
 
-/* Used by the back end to look up addresses of helper
-   function calls inserted by bbToIR_X86Instr. */
-extern
-HWord x86guest_findhelper ( Char* function_name );
-
 /* Used by the optimiser to specialise calls to helpers. */
 extern
 IRExpr* x86guest_spechelper ( Char* function_name,
@@ -46,6 +41,24 @@ extern
 VexGuestLayoutInfo x86guest_layout;
 
 
+/*---------------------------------------------------------*/
+/*--- x86 guest helpers                                 ---*/
+/*---------------------------------------------------------*/
+
+/* --- CLEAN HELPERS --- */
+extern UInt  calculate_eflags_all ( UInt cc_op, UInt cc_src, UInt cc_dst );
+extern UInt  calculate_eflags_c   ( UInt cc_op, UInt cc_src, UInt cc_dst );
+extern UInt  calculate_condition  ( UInt/*Condcode*/ cond, 
+                                    UInt cc_op, UInt cc_src, UInt cc_dst );
+extern UInt  calculate_FXAM ( UInt tag, ULong dbl );
+extern ULong calculate_RCR  ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz );
+
+/* --- DIRTY HELPERS --- */
+extern ULong loadF80le  ( UInt );
+extern void  storeF80le ( UInt, ULong );
+extern void  dirtyhelper_CPUID ( VexGuestX86State* );
+
+
 /*---------------------------------------------------------*/
 /*--- Condition code stuff                              ---*/
 /*---------------------------------------------------------*/
index b564bab3538f2c164485422fa6017f7a5ca79f11..50dea82418e5ad474af4805fe25da1afd34109d2 100644 (file)
 #include "main/vex_util.h"
 #include "guest-x86/gdefs.h"
 
-/* --- Forwardses --- */
-
-/* --- CLEAN HELPERS --- */
-static UInt  calculate_eflags_all ( UInt cc_op, UInt cc_src, UInt cc_dst );
-static UInt  calculate_eflags_c   ( UInt cc_op, UInt cc_src, UInt cc_dst );
-static UInt  calculate_condition  ( UInt/*Condcode*/ cond, 
-                                    UInt cc_op, UInt cc_src, UInt cc_dst );
-static UInt  calculate_FXAM ( UInt tag, ULong dbl );
-static ULong calculate_RCR  ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz );
-
-/* --- DIRTY HELPERS --- */
-static ULong loadF80le  ( UInt );
-static void  storeF80le ( UInt, ULong );
-static void  dirtyhelper_CPUID ( VexGuestX86State* );
-
 
 /* This file contains helper functions for x86 guest code.
    Calls to these functions are generated by the back end.
@@ -413,7 +398,6 @@ static void initCounts ( void )
 
 /* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* Calculate all the 6 flags from the supplied thunk parameters. */
-static
 UInt calculate_eflags_all ( UInt cc_op, UInt cc_src_formal, UInt cc_dst_formal )
 {
 #  if PROFILE_EFLAGS
@@ -488,7 +472,7 @@ UInt calculate_eflags_all ( UInt cc_op, UInt cc_src_formal, UInt cc_dst_formal )
 
 /* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* Calculate just the carry flag from the supplied thunk parameters. */
-static UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
+UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
 {
    /* Fast-case some common ones. */
    switch (cc_op) {
@@ -597,27 +581,6 @@ static UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
 }
 
 
-HWord x86guest_findhelper ( Char* function_name )
-{
-   if (vex_streq(function_name, "calculate_condition"))
-      return (HWord)(& calculate_condition);
-   if (vex_streq(function_name, "calculate_eflags_c"))
-      return (HWord)(& calculate_eflags_c);
-   if (vex_streq(function_name, "calculate_eflags_all"))
-      return (HWord)(& calculate_eflags_all);
-   if (vex_streq(function_name, "calculate_FXAM"))
-      return (HWord)(& calculate_FXAM);
-   if (vex_streq(function_name, "storeF80le"))
-      return (HWord)(& storeF80le);
-   if (vex_streq(function_name, "loadF80le"))
-      return (HWord)(& loadF80le);
-   if (vex_streq(function_name, "calculate_RCR"))
-      return (HWord)(& calculate_RCR);
-   if (vex_streq(function_name, "dirtyhelper_CPUID"))
-      return (HWord)(& dirtyhelper_CPUID);
-   return 0; /* not found */
-}
-
 /* Used by the optimiser to try specialisations.  Returns an
    equivalent expression, or NULL if none. */
 
@@ -858,7 +821,7 @@ static inline Bool host_is_little_endian ( void )
 }
 
 /* CALLED FROM GENERATED CODE: CLEAN HELPER */
-static UInt calculate_FXAM ( UInt tag, ULong dbl ) 
+UInt calculate_FXAM ( UInt tag, ULong dbl ) 
 {
    Bool   mantissaIsZero;
    Int    bexp;
@@ -1192,7 +1155,7 @@ static void convert_f80le_to_f64le ( /*IN*/UChar* f80, /*OUT*/UChar* f64 )
 
 /* CALLED FROM GENERATED CODE */
 /* DIRTY HELPER (reads guest memory) */
-static ULong loadF80le ( UInt addrU )
+ULong loadF80le ( UInt addrU )
 {
    ULong f64;
    convert_f80le_to_f64le ( (UChar*)addrU, (UChar*)&f64 );
@@ -1201,7 +1164,7 @@ static ULong loadF80le ( UInt addrU )
 
 /* CALLED FROM GENERATED CODE */
 /* DIRTY HELPER (writes guest memory) */
-static void storeF80le ( UInt addrU, ULong f64 )
+void storeF80le ( UInt addrU, ULong f64 )
 {
    convert_f64le_to_f80le( (UChar*)&f64, (UChar*)addrU );
 }
@@ -1393,7 +1356,7 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
    through the carry bit.  Result in low 32 bits, 
    new flags (OSZACP) in high 32 bits.
 */
-static ULong calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
+ULong calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
 {
    UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf;
 
@@ -1446,7 +1409,7 @@ static ULong calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
 /* CALLED FROM GENERATED CODE */
 /* DIRTY HELPER (modifies guest state) */
 /* Claim to be a P54C P133 (pre-MMX Pentium) */
-static void dirtyhelper_CPUID ( VexGuestX86State* st )
+void dirtyhelper_CPUID ( VexGuestX86State* st )
 {
    if (st->guest_EAX == 0) {
       st->guest_EAX = 0x1;
index 906a601d0d56fbeeba64b32e9f19d973c2793682..84929efcbfb335295e1d2d8423c663142b9815de 100644 (file)
@@ -590,7 +590,12 @@ static IRExpr* mk_calculate_eflags_all ( void )
    args[1]       = IRExpr_Get(OFFB_CC_SRC, Ity_I32);
    args[2]       = IRExpr_Get(OFFB_CC_DST, Ity_I32);
    args[3]       = NULL;
-   return IRExpr_CCall("calculate_eflags_all", Ity_I32, args);
+   return IRExpr_CCall(
+             mkIRCallee(0/*regparm*/, "calculate_eflags_all", 
+                        (HWord)&calculate_eflags_all),
+             Ity_I32, 
+             args
+          );
 }
 
 /* Build IR to calculate just the carry flag from stored
@@ -602,12 +607,17 @@ static IRExpr* mk_calculate_eflags_c ( void )
    args[1]       = IRExpr_Get(OFFB_CC_SRC, Ity_I32);
    args[2]       = IRExpr_Get(OFFB_CC_DST, Ity_I32);
    args[3]       = NULL;
-   return IRExpr_CCall("calculate_eflags_c", Ity_I32, args);
+   return IRExpr_CCall(
+             mkIRCallee(0/*regparm*/, "calculate_eflags_c", 
+                        (HWord)&calculate_eflags_c),
+             Ity_I32, 
+             args
+          );
 }
 
 /* Build IR to calculate some particular condition from stored
    CC_OP/CC_SRC/CC_DST.  Returns an expression :: Ity_Bit. */
-static IRExpr* calculate_condition ( Condcode cond )
+static IRExpr* mk_calculate_condition ( Condcode cond )
 {
    IRExpr** args = LibVEX_Alloc(5 * sizeof(IRExpr*));
    args[0]       = mkU32(cond);
@@ -616,7 +626,13 @@ static IRExpr* calculate_condition ( Condcode cond )
    args[3]       = IRExpr_Get(OFFB_CC_DST, Ity_I32);
    args[4]       = NULL;
    return unop(Iop_32to1, 
-               IRExpr_CCall("calculate_condition", Ity_I32, args));
+               IRExpr_CCall(
+                  mkIRCallee(0/*regparm*/, "calculate_condition", 
+                             (HWord)&calculate_condition),
+                  Ity_I32, 
+                  args
+               )
+              );
 }
 
 
@@ -1371,12 +1387,12 @@ static void jcc_01( Condcode cond, Addr32 d32_false, Addr32 d32_true )
    Condcode condPos;
    condPos = positiveIse_Condcode ( cond, &invert );
    if (invert) {
-      stmt( IRStmt_Exit( calculate_condition(condPos),
+      stmt( IRStmt_Exit( mk_calculate_condition(condPos),
                          IRConst_U32(d32_false) ) );
       irbb->next     = mkU32(d32_true);
       irbb->jumpkind = Ijk_Boring;
    } else {
-      stmt( IRStmt_Exit( calculate_condition(condPos),
+      stmt( IRStmt_Exit( mk_calculate_condition(condPos),
                          IRConst_U32(d32_true) ) );
       irbb->next     = mkU32(d32_false);
       irbb->jumpkind = Ijk_Boring;
@@ -2353,11 +2369,16 @@ UInt dis_Grp2 ( UChar  sorb,
       IRTemp   r64  = newTemp(Ity_I64);
       IRExpr** args = LibVEX_Alloc(5 * sizeof(IRExpr*));
       args[0] = widenUto32(mkexpr(dst0)); /* thing to rotate */
-      args[1] = widenUto32(shift_expr);  /* rotate amount */
+      args[1] = widenUto32(shift_expr);   /* rotate amount */
       args[2] = widenUto32(mk_calculate_eflags_all());
       args[3] = mkU32(sz);
       args[4] = NULL;
-      assign( r64, IRExpr_CCall("calculate_RCR", Ity_I64, args) );
+      assign( r64, IRExpr_CCall(
+                      mkIRCallee(0/*regparm*/, "calculate_RCR", 
+                                 (HWord)&calculate_RCR),
+                      Ity_I64, 
+                      args
+            ));
       /* new eflags in hi half r64; new value in lo half r64 */
       assign( dst1, narrowTo(ty, unop(Iop_64to32, mkexpr(r64))) );
       stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
@@ -3152,7 +3173,7 @@ void dis_REP_op ( Condcode cond,
    if (cond == CondAlways) {
       jmp_lit(Ijk_Boring,eip);
    } else {
-      stmt( IRStmt_Exit( calculate_condition(cond),
+      stmt( IRStmt_Exit( mk_calculate_condition(cond),
                         IRConst_U32(eip) ) );
       jmp_lit(Ijk_Boring,eip_next);
    }
@@ -3772,7 +3793,12 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                args[0] = unop(Iop_8Uto32, get_ST_TAG(0));
                args[1] = unop(Iop_ReinterpF64asI64, get_ST_UNCHECKED(0));
                args[2] = NULL;
-               put_C3210(IRExpr_CCall("calculate_FXAM", Ity_I32, args));
+               put_C3210(IRExpr_CCall(
+                            mkIRCallee(0/*regparm*/, "calculate_FXAM", 
+                                       (HWord)&calculate_FXAM), 
+                            Ity_I32, 
+                            args
+                        ));
                break;
             }
 
@@ -3989,7 +4015,7 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
               DIP("fcmovz %%st(%d), %%st(0)", r_src);
               put_ST_UNCHECKED(0, 
                                 IRExpr_Mux0X( 
-                                    unop(Iop_1Uto8,calculate_condition(CondZ)), 
+                                    unop(Iop_1Uto8,mk_calculate_condition(CondZ)), 
                                     get_ST(0), get_ST(r_src)) );
                break;
 
@@ -4054,7 +4080,11 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                IRTemp   val  = newTemp(Ity_I64);
                IRExpr** args = mkIRExprVec_1 ( mkexpr(addr) );
 
-               IRDirty* d = unsafeIRDirty_1_N ( val, "loadF80le", args );
+               IRDirty* d = unsafeIRDirty_1_N ( 
+                               val, 
+                               mkIRCallee(0, "loadF80le", (HWord)&loadF80le), 
+                               args 
+                            );
                /* declare that we're reading memory */
                d->mFx   = Ifx_Read;
                d->mAddr = mkexpr(addr);
@@ -4075,7 +4105,11 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                   = mkIRExprVec_2( mkexpr(addr), 
                                    unop(Iop_ReinterpF64asI64, get_ST(0)) );
 
-               IRDirty* d = unsafeIRDirty_0_N ( "storeF80le", args );
+               IRDirty* d = unsafeIRDirty_0_N ( 
+                               mkIRCallee(0, "storeF80le", 
+                                             (HWord)&storeF80le), 
+                               args 
+                            );
                /* declare we're writing memory */
                d->mFx   = Ifx_Write;
                d->mAddr = mkexpr(addr);
@@ -4105,7 +4139,7 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
               DIP("fcmovnz %%st(%d), %%st(0)", r_src);
               put_ST_UNCHECKED(0, 
                                 IRExpr_Mux0X( 
-                                    unop(Iop_1Uto8,calculate_condition(CondNZ)), 
+                                    unop(Iop_1Uto8,mk_calculate_condition(CondNZ)), 
                                     get_ST(0), get_ST(r_src)) );
                break;
 
@@ -5230,7 +5264,7 @@ UInt dis_cmpxchg_G_E ( UChar       sorb,
    assign( src, getIReg(size, gregOfRM(rm)) );
    assign( acc, getIReg(size, R_EAX) );
    setFlags_ADD_SUB(Iop_Sub8, dest, acc, ty);
-   assign( cond8, unop(Iop_1Uto8, calculate_condition(CondZ)) );
+   assign( cond8, unop(Iop_1Uto8, mk_calculate_condition(CondZ)) );
    assign( dest2, IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(src)) );
    assign( acc2,  IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(acc)) );
    putIReg(size, R_EAX, mkexpr(acc2));
@@ -5349,7 +5383,7 @@ UInt dis_cmov_E_G ( UChar       sorb,
       assign( tmpd, getIReg(sz, gregOfRM(rm)) );
 
       putIReg(sz, gregOfRM(rm),
-                  IRExpr_Mux0X( unop(Iop_1Uto8,calculate_condition(cond)),
+                  IRExpr_Mux0X( unop(Iop_1Uto8,mk_calculate_condition(cond)),
                                 mkexpr(tmpd),
                                 mkexpr(tmps) )
              );
@@ -5367,7 +5401,7 @@ UInt dis_cmov_E_G ( UChar       sorb,
       assign( tmpd, getIReg(sz, gregOfRM(rm)) );
 
       putIReg(sz, gregOfRM(rm),
-                  IRExpr_Mux0X( unop(Iop_1Uto8,calculate_condition(cond)),
+                  IRExpr_Mux0X( unop(Iop_1Uto8,mk_calculate_condition(cond)),
                                 mkexpr(tmpd),
                                 mkexpr(tmps) )
              );
@@ -8970,7 +9004,11 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
             declared to mod eax, wr ebx, ecx, edx
          */
          IRExpr** args = mkIRExprVec_0();
-         IRDirty* d    = unsafeIRDirty_0_N ( "dirtyhelper_CPUID", args );
+         IRDirty* d    = unsafeIRDirty_0_N ( 
+                            mkIRCallee(0, "dirtyhelper_CPUID", 
+                                          (HWord)&dirtyhelper_CPUID), 
+                            args 
+                         );
          /* declare guest state effects */
          d->needsBBP = True;
          d->nFxState = 4;
@@ -9145,7 +9183,7 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
       case 0x9E: /* set-LEb/set-NGb (jump less or equal) */
       case 0x9F: /* set-Gb/set-NLEb (jump greater) */
         t1 = newTemp(Ity_I8);
-        assign( t1, unop(Iop_1Uto8,calculate_condition(opc-0x90)) );
+        assign( t1, unop(Iop_1Uto8,mk_calculate_condition(opc-0x90)) );
          modrm = getIByte(delta);
          if (epartIsReg(modrm)) {
             delta++;
index fd00ef9af041557332801c941b48ab5f34fa91dc..768c8b9f25442c7b771c2f0fcd73b82cc62b61fa 100644 (file)
@@ -477,8 +477,7 @@ extern Int          emit_X86Instr        ( UChar* buf, Int nbuf, X86Instr* );
 extern X86Instr*    genSpill_X86         ( HReg rreg, Int offset );
 extern X86Instr*    genReload_X86        ( HReg rreg, Int offset );
 extern void         getAllocableRegs_X86 ( Int*, HReg** );
-extern HInstrArray* iselBB_X86           ( IRBB*, HWord(*)(Char*), 
-                                                  HWord(*)(Char*) );
+extern HInstrArray* iselBB_X86           ( IRBB* );
 
 #endif /* ndef __LIBVEX_X86H_DEFS_H */
 
index e63a557077e26a7887811843628341645b52abc0..f3466a4c79693f1f694cc13ef1062d2a0b5307a0 100644 (file)
@@ -143,12 +143,6 @@ static IRExpr* bind ( Int binder )
 
 /* This carries around:
 
-   - A function for looking up the address of vex front-end supplied
-     helper functions.
-
-   - A function for looking up the address of tool-supplied helper
-     functions.
-
    - A mapping from IRTemp to IRType, giving the type of any IRTemp we
      might encounter.  This is computed before insn selection starts,
      and does not change.
@@ -173,9 +167,6 @@ static IRExpr* bind ( Int binder )
 
 typedef
    struct {
-      HWord        (*find_helper_vex)(Char*);
-      HWord        (*find_helper_tool)(Char*);
-
       IRTypeEnv*   type_env;
 
       HReg*        vregmap;
@@ -301,47 +292,16 @@ static Int pushArg ( ISelEnv* env, IRExpr* arg )
 }
 
 
-/* Find the address of a helper function, first by consulting vex's
-   own front end, and if that doesn't work, by consulting the
-   tool-supplied lookup function. */
-
-static
-HWord findHelper ( ISelEnv* env, Char* name )
-{
-   HWord helper;
-
-   /* Since the host -- for which we are generating code, and on which
-      the helpers are compiled -- is a 32-bit machine (x86) -- HWord
-      must be a 32-bit type. */
-   vassert(sizeof(HWord) == 4);
-
-   /* First see if vex's own front end has a binding for this fn. */
-   helper = env->find_helper_vex(name);
-
-   /* No?  Try the tool-supplied function. */
-   if (helper == 0 && env->find_helper_tool)
-      helper = env->find_helper_tool(name);
-
-   if (helper != 0)
-      return helper;
-
-   vex_printf("\nvex x86 back end: can't find helper: %s\n", name);
-   vpanic("findHelper(x86,host)");
-}
-
-
 /* Complete the call to a helper function, by calling the 
    helper and clearing the args off the stack. */
 
 static 
-void callHelperAndClearArgs ( ISelEnv* env, Char* name, Int n_arg_ws )
+void callHelperAndClearArgs ( ISelEnv* env, IRCallee* cee, Int n_arg_ws )
 {
-   HWord helper = findHelper( env, name );
    vassert(sizeof(HWord) == 4);
-
    addInstr(env, X86Instr_Alu32R(
                     Xalu_MOV,
-                    X86RMI_Imm(helper),
+                    X86RMI_Imm(cee->addr),
                     hregX86_EAX()));
    addInstr(env, X86Instr_Call(hregX86_EAX()));
    if (n_arg_ws > 0)
@@ -919,7 +879,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          n_arg_ws += pushArg(env, e->Iex.CCall.args[i]);
 
       /* call the helper, and get the args off the stack afterwards. */
-      callHelperAndClearArgs( env, e->Iex.CCall.name, n_arg_ws );
+      callHelperAndClearArgs( env, e->Iex.CCall.cee, n_arg_ws );
 
       addInstr(env, mk_MOVsd_RR(hregX86_EAX(), dst));
       return dst;
@@ -1654,7 +1614,7 @@ static void iselIntExpr64_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e )
          n_arg_ws += pushArg(env, e->Iex.CCall.args[i]);
 
       /* call the helper, and get the args off the stack afterwards. */
-      callHelperAndClearArgs( env, e->Iex.CCall.name, n_arg_ws );
+      callHelperAndClearArgs( env, e->Iex.CCall.cee, n_arg_ws );
 
       addInstr(env, mk_MOVsd_RR(hregX86_EDX(), tHi));
       addInstr(env, mk_MOVsd_RR(hregX86_EAX(), tLo));
@@ -2173,7 +2133,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
       }
 
       /* call the helper, and get the args off the stack afterwards. */
-      callHelperAndClearArgs( env, d->name, n_arg_ws );
+      callHelperAndClearArgs( env, d->cee, n_arg_ws );
 
       /* Now figure out what to do with the returned value, if any. */
       if (d->tmp == INVALID_IRTEMP)
@@ -2237,9 +2197,7 @@ static void iselNext ( ISelEnv* env, IRExpr* next, IRJumpKind jk )
 
 /* Translate an entire BB to x86 code. */
 
-HInstrArray* iselBB_X86 ( IRBB* bb, 
-                          HWord(*find_helper_vex)(Char*),
-                          HWord(*find_helper_tool)(Char*) )
+HInstrArray* iselBB_X86 ( IRBB* bb )
 {
    Int     i, j;
    HReg    hreg, hregHI;
@@ -2248,10 +2206,6 @@ HInstrArray* iselBB_X86 ( IRBB* bb,
    ISelEnv* env = LibVEX_Alloc(sizeof(ISelEnv));
    env->vreg_ctr = 0;
 
-   /* Register helper-function-finders. */
-   env->find_helper_vex  = find_helper_vex;
-   env->find_helper_tool = find_helper_tool;
-
    /* Set up output code array. */
    env->code = newHInstrArray();
 
index 935d36815664fc06bbfdbee67f16682f1a3c961a..19b30ec686ac0059d0bf2a54f2e2f49d754a36e4 100644 (file)
@@ -48,6 +48,14 @@ void ppIRConst ( IRConst* con )
    }
 }
 
+void ppIRCallee ( IRCallee* ce )
+{
+   vex_printf("%s", ce->name);
+   if (ce->regparm > 0)
+      vex_printf("[%d]", ce->regparm);
+   vex_printf("{%p}", (void*)ce->addr);
+}
+
 void ppIRArray ( IRArray* arr )
 {
    vex_printf("(%d:%dx", arr->base, arr->nElems);
@@ -237,7 +245,8 @@ void ppIRExpr ( IRExpr* e )
       ppIRConst(e->Iex.Const.con);
       break;
     case Iex_CCall:
-      vex_printf("%s(", e->Iex.CCall.name);
+      ppIRCallee(e->Iex.CCall.cee);
+      vex_printf("(");
       for (i = 0; e->Iex.CCall.args[i] != NULL; i++) {
         ppIRExpr(e->Iex.CCall.args[i]);
         if (e->Iex.CCall.args[i+1] != NULL)
@@ -294,7 +303,8 @@ void ppIRDirty ( IRDirty* d )
       ppIRTemp(d->tmp);
       vex_printf(" = ");
    }
-   vex_printf("%s(", d->name);
+   ppIRCallee(d->cee);
+   vex_printf("(");
    for (i = 0; d->args[i] != NULL; i++) {
       ppIRExpr(d->args[i]);
       if (d->args[i+1] != NULL) {
@@ -453,7 +463,22 @@ IRConst* IRConst_F64i ( ULong f64i )
 }
 
 
-/* Constructors -- IRExpr */
+/* Constructors -- IRCallee */
+
+IRCallee* mkIRCallee ( Int regparm, Char* name, HWord addr )
+{
+   IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee));
+   ce->regparm = regparm;
+   ce->name = name;
+   ce->addr = addr;
+   vassert(regparm >= 0);
+   vassert(name != NULL);
+   vassert(addr != 0);
+   return ce;
+}
+
+
+/* Constructors -- IRArray */
 
 IRArray* mkIRArray ( Int base, IRType elemTy, Int nElems )
 {
@@ -525,10 +550,10 @@ IRExpr* IRExpr_Const ( IRConst* con ) {
    e->Iex.Const.con = con;
    return e;
 }
-IRExpr* IRExpr_CCall ( Char* name, IRType retty, IRExpr** args ) {
+IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) {
    IRExpr* e          = LibVEX_Alloc(sizeof(IRExpr));
    e->tag             = Iex_CCall;
-   e->Iex.CCall.name  = name;
+   e->Iex.CCall.cee   = cee;
    e->Iex.CCall.retty = retty;
    e->Iex.CCall.args  = args;
    return e;
@@ -570,7 +595,7 @@ IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) {
 
 IRDirty* emptyIRDirty ( void ) {
    IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
-   d->name     = NULL;
+   d->cee      = NULL;
    d->args     = NULL;
    d->tmp      = INVALID_IRTEMP;
    d->mFx      = Ifx_None;
@@ -581,15 +606,15 @@ IRDirty* emptyIRDirty ( void ) {
    return d;
 }
 
-IRDirty* unsafeIRDirty_0_N ( Char* name, IRExpr** args ) {
+IRDirty* unsafeIRDirty_0_N ( IRCallee* cee, IRExpr** args ) {
    IRDirty* d = emptyIRDirty();
-   d->name = name;
+   d->cee  = cee;
    d->args = args;
    return d;
 }
-IRDirty* unsafeIRDirty_1_N ( IRTemp dst, Char* name, IRExpr** args ) {
+IRDirty* unsafeIRDirty_1_N ( IRTemp dst, IRCallee* cee, IRExpr** args ) {
    IRDirty* d = emptyIRDirty();
-   d->name = name;
+   d->cee  = cee;
    d->args = args;
    d->tmp  = dst;
    return d;
@@ -722,6 +747,11 @@ IRConst* dopyIRConst ( IRConst* c )
    }
 }
 
+IRCallee* dopyIRCallee ( IRCallee* ce )
+{
+   return mkIRCallee(ce->regparm, ce->name, ce->addr);
+}
+
 IRArray* dopyIRArray ( IRArray* d )
 {
    return mkIRArray(d->base, d->elemTy, d->nElems);
@@ -751,7 +781,7 @@ IRExpr* dopyIRExpr ( IRExpr* e )
       case Iex_Const: 
          return IRExpr_Const(dopyIRConst(e->Iex.Const.con));
       case Iex_CCall:
-         return IRExpr_CCall(e->Iex.CCall.name,
+         return IRExpr_CCall(dopyIRCallee(e->Iex.CCall.cee),
                              e->Iex.CCall.retty,
                              dopyIRExprVec(e->Iex.CCall.args));
 
@@ -768,7 +798,7 @@ IRDirty* dopyIRDirty ( IRDirty* d )
 {
    Int      i;
    IRDirty* d2 = emptyIRDirty();
-   d2->name  = d->name;
+   d2->cee   = dopyIRCallee(d->cee);
    d2->args  = dopyIRExprVec(d->args);
    d2->tmp   = d->tmp;
    d2->mFx   = d->mFx;
@@ -1144,6 +1174,17 @@ static Bool saneIRArray ( IRArray* arr )
    return True;
 }
 
+static Bool saneIRCallee ( IRCallee* cee )
+{
+   if (cee->name == NULL)
+      return False;
+   if (cee->addr == 0)
+      return False;
+   if (cee->regparm < 0 || cee->regparm > 3)
+      return False;
+   return True;
+}
+
 
 /* Traverse a Stmt/Expr, inspecting IRTemp uses.  Report any out of
    range ones.  Report any which are read and for which the current
@@ -1367,7 +1408,8 @@ void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy )
       case Ist_Dirty:
          /* Mostly check for various kinds of ill-formed dirty calls. */
          d = stmt->Ist.Dirty.details;
-         if (d->name == NULL) goto bad_dirty;
+         if (d->cee == NULL) goto bad_dirty;
+         if (!saneIRCallee(d->cee)) goto bad_dirty;
          if (d->mFx == Ifx_None) {
             if (d->mAddr != NULL || d->mSize != 0)
                goto bad_dirty;
index b31814c3c48f713a2780249e87baa2f017ca2445..48abdfa3d32f1e432401a64e14c9f37e84daa00e 100644 (file)
@@ -220,7 +220,7 @@ static IRExpr* flatten_Expr ( IRBB* bb, IRExpr* ex )
             newargs[i] = flatten_Expr(bb, newargs[i]);
          t1 = newIRTemp(bb->tyenv, ty);
          addStmtToIRBB(bb, IRStmt_Tmp(t1,
-            IRExpr_CCall(ex->Iex.CCall.name,
+            IRExpr_CCall(ex->Iex.CCall.cee,
                          ex->Iex.CCall.retty,
                          newargs)));
          return IRExpr_Tmp(t1);
@@ -656,7 +656,7 @@ static IRExpr* subst_Expr ( IRExpr** env, IRExpr* ex )
             args2[i] = subst_Expr(env, args2[i]);
          }
          return IRExpr_CCall(
-                   ex->Iex.CCall.name,
+                   ex->Iex.CCall.cee,
                    ex->Iex.CCall.retty,
                    args2 
                 );
@@ -1362,7 +1362,7 @@ void spec_helpers_BB ( IRBB* bb,
           || st->Ist.Tmp.data->tag != Iex_CCall)
         continue;
 
-      ex = (*specHelper)( st->Ist.Tmp.data->Iex.CCall.name,
+      ex = (*specHelper)( st->Ist.Tmp.data->Iex.CCall.cee->name,
                           st->Ist.Tmp.data->Iex.CCall.args );
       if (!ex)
         /* the front end can't think of a suitable replacement */
@@ -1548,7 +1548,7 @@ static IRExpr* tbSubst_Expr ( TmpInfo** env, IRExpr* e )
          args2 = sopyIRExprVec(e->Iex.CCall.args);
          for (i = 0; args2[i]; i++)
             args2[i] = tbSubst_Expr(env,args2[i]);
-         return IRExpr_CCall(e->Iex.CCall.name,
+         return IRExpr_CCall(e->Iex.CCall.cee,
                    e->Iex.CCall.retty,
                    args2
                 );
index 1baf976c377c1846f8a395848b36ab8a2a1e5bde..d61c561d077520a8b473c47155891ff4da03425c 100644 (file)
@@ -128,7 +128,6 @@ TranslateResult LibVEX_Translate (
    /* IN: optionally, two instrumentation functions. */
    IRBB* (*instrument1) ( IRBB*, VexGuestLayoutInfo* ),
    IRBB* (*instrument2) ( IRBB*, VexGuestLayoutInfo* ),
-   HWord (*tool_findhelper) ( Char* ),
    /* IN: optionally, an access check function for guest code. */
    Bool (*byte_accessible) ( Addr64 ),
    /* IN: debug: trace vex activity at various points */
@@ -147,11 +146,10 @@ TranslateResult LibVEX_Translate (
    HInstr*      (*genReload)   ( HReg, Int );
    void         (*ppInstr)     ( HInstr* );
    void         (*ppReg)       ( HReg );
-   HInstrArray* (*iselBB)      ( IRBB*, HWord(*)(Char*), HWord(*)(Char*) );
+   HInstrArray* (*iselBB)      ( IRBB* );
    IRBB*        (*bbToIR)      ( UChar*, Addr64, Int*, 
                                          Bool(*)(Addr64), Bool );
    Int          (*emit)        ( UChar*, Int, HInstr* );
-   HWord        (*findHelper)  ( Char* );
    IRExpr*      (*specHelper)  ( Char*, IRExpr** );
    Bool         (*preciseMemExnsFn) ( Int, Int );
 
@@ -177,7 +175,6 @@ TranslateResult LibVEX_Translate (
    iselBB                 = NULL;
    bbToIR                 = NULL;
    emit                   = NULL;
-   findHelper             = NULL;
    specHelper             = NULL;
    preciseMemExnsFn       = NULL;
    guest_word_size        = Ity_INVALID;
@@ -212,7 +209,6 @@ TranslateResult LibVEX_Translate (
       case InsnSetX86:
          preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
          bbToIR           = bbToIR_X86Instr;
-         findHelper       = x86guest_findhelper;
          specHelper       = x86guest_spechelper;
          guest_sizeB      = sizeof(VexGuestX86State);
         guest_word_size  = Ity_I32;
@@ -299,7 +295,7 @@ TranslateResult LibVEX_Translate (
                    " Instruction selection "
                    "------------------------\n");
 
-   vcode = iselBB ( irbb, findHelper, tool_findhelper );
+   vcode = iselBB ( irbb );
 
    if (vex_traceflags & VEX_TRACE_VCODE)
       vex_printf("\n");
index 58412ee7354269f2afeb3a417533dffb0fb6f0e7..e69b8cc3495b8db0718996dfbd1a6f568bed3a2c 100644 (file)
@@ -129,7 +129,6 @@ TranslateResult LibVEX_Translate (
    /* IN: optionally, two instrumentation functions. */
    IRBB* (*instrument1) ( IRBB*, VexGuestLayoutInfo* ),
    IRBB* (*instrument2) ( IRBB*, VexGuestLayoutInfo* ),
-   HWord (*tool_findhelper) ( Char* ),
    /* IN: optionally, an access check function for guest code. */
    Bool (*byte_accessible) ( Addr64 ),
    /* IN: debug: trace vex activity at various points */
index 3bc311c03bd3315fb703c83910aabc93b52cc5b0..a6130d62c440f54c5d669b117be84933872dd687 100644 (file)
@@ -70,6 +70,30 @@ extern void ppIRConst ( IRConst* );
 extern Bool eqIRConst ( IRConst*, IRConst* );
 
 
+/* ------------------ Call targets ------------------ */
+
+/* Describes a helper function to call.  The name part is purely for
+   pretty printing and not actually used.  regparm=n tells the back
+   end that the callee has been declared
+   "__attribute__((regparm(n)))".  On some targets (x86) the back end
+   will need to construct a non-standard sequence to call a function
+   declared like this. */
+
+typedef
+   struct {
+      Int   regparm;
+      Char* name;
+      HWord addr;
+   }
+   IRCallee;
+
+extern IRCallee* mkIRCallee ( Int regparm, Char* name, HWord addr );
+
+extern IRCallee* dopyIRCallee ( IRCallee* );
+
+extern void ppIRCallee ( IRCallee* );
+
+
 /* ------------------ Guest state arrays ------------------ */
 
 typedef
@@ -378,8 +402,8 @@ typedef
             IRConst* con;
          } Const;
          struct {
-            Char*  name;
-            IRType retty;
+            IRCallee* cee;
+            IRType    retty;
             struct _IRExpr** args;
          }  CCall;
          struct {
@@ -399,7 +423,7 @@ extern IRExpr* IRExpr_Binop  ( IROp op, IRExpr* arg1, IRExpr* arg2 );
 extern IRExpr* IRExpr_Unop   ( IROp op, IRExpr* arg );
 extern IRExpr* IRExpr_LDle   ( IRType ty, IRExpr* addr );
 extern IRExpr* IRExpr_Const  ( IRConst* con );
-extern IRExpr* IRExpr_CCall  ( Char* name, IRType retty, IRExpr** args );
+extern IRExpr* IRExpr_CCall  ( IRCallee* cee, IRType retty, IRExpr** args );
 extern IRExpr* IRExpr_Mux0X  ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
 
 extern IRExpr*  dopyIRExpr ( IRExpr* );
@@ -479,14 +503,14 @@ extern void ppIREffect ( IREffect );
 typedef
    struct {
       /* What to call, and details of args/results */
-      Char*    name;   /* name of the function to call */
-      IRExpr** args;   /* arg list, ends in NULL */
-      IRTemp   tmp;    /* to assign result to, or INVALID_IRTEMP if none */
+      IRCallee* cee;    /* where to call */
+      IRExpr**  args;   /* arg list, ends in NULL */
+      IRTemp    tmp;    /* to assign result to, or INVALID_IRTEMP if none */
 
       /* Mem effects; we allow only one R/W/M region to be stated */
-      IREffect mFx;    /* indicates memory effects, if any */
-      IRExpr*  mAddr;  /* of access, or NULL if mFx==Ifx_None */
-      Int      mSize;  /* of access, or zero if mFx==Ifx_None */
+      IREffect  mFx;    /* indicates memory effects, if any */
+      IRExpr*   mAddr;  /* of access, or NULL if mFx==Ifx_None */
+      Int       mSize;  /* of access, or zero if mFx==Ifx_None */
 
       /* Guest state effects; up to N allowed */
       Bool needsBBP; /* True => also pass guest state ptr to callee */
@@ -509,11 +533,11 @@ extern IRDirty* dopyIRDirty ( IRDirty* );
    any value.  The call is marked as accessing neither guest state nor
    memory (hence the "unsafe" designation) -- you can mess with this
    later if need be.*/
-extern IRDirty* unsafeIRDirty_0_N ( Char* name, IRExpr** args );
+extern IRDirty* unsafeIRDirty_0_N ( IRCallee* cee, IRExpr** args );
 
 /* Similarly, make a zero-annotation dirty call which returns a value,
    and assign that to the given temp. */
-extern IRDirty* unsafeIRDirty_1_N ( IRTemp dst, Char* name, IRExpr** args );
+extern IRDirty* unsafeIRDirty_1_N ( IRTemp dst, IRCallee* cee, IRExpr** args );
 
 
 /* ------------------ Statements ------------------ */