]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add mechanisms for calling helper functions from generated code.
authorJulian Seward <jseward@acm.org>
Sat, 24 Jul 2004 13:12:23 +0000 (13:12 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 24 Jul 2004 13:12:23 +0000 (13:12 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@112

VEX/Makefile
VEX/Makefile-icc
VEX/priv/guest-x86/x86guest_defs.h
VEX/priv/guest-x86/x86helpers.c [new file with mode: 0644]
VEX/priv/host-x86/isel_x86.c
VEX/priv/host-x86/x86host_defs.c
VEX/priv/host-x86/x86host_defs.h
VEX/priv/main/vex_main.c
VEX/priv/main/vex_util.c
VEX/priv/main/vex_util.h

index 8608a16e9810becb4bbd2acfaeb073e2e947339d..d102ae15c32e1d37e47cf17986af985f955918e2 100644 (file)
@@ -17,6 +17,7 @@ LIB_OBJS =    priv/ir/ir_defs.o                       \
                priv/host-x86/isel_x86.o                \
                priv/host-generic/host_regs.o           \
                priv/host-generic/reg_alloc.o           \
+               priv/guest-x86/x86helpers.o             \
                priv/guest-x86/x86toIR.o
 
 PUB_INCLUDES = -Ipub
@@ -97,4 +98,8 @@ priv/host-generic/reg_alloc.o: $(ALL_HEADERS) priv/host-generic/reg_alloc.c
 
 priv/guest-x86/x86toIR.o: $(ALL_HEADERS) priv/guest-x86/x86toIR.c
        $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest-x86/x86toIR.o \
-                                        -c priv/guest-x86/x86toIR.c
\ No newline at end of file
+                                        -c priv/guest-x86/x86toIR.c
+
+priv/guest-x86/x86helpers.o: $(ALL_HEADERS) priv/guest-x86/x86helpers.c
+       $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest-x86/x86helpers.o \
+                                        -c priv/guest-x86/x86helpers.c
index 037e605632210165262807fbb2dd6dd044277ace..720a4cf9eb010eb354bc5f86fbff7ec813f6867c 100644 (file)
@@ -17,6 +17,7 @@ LIB_OBJS =    priv/ir/ir_defs.o                       \
                priv/host-x86/isel_x86.o                \
                priv/host-generic/host_regs.o           \
                priv/host-generic/reg_alloc.o           \
+               priv/guest-x86/x86helpers.o             \
                priv/guest-x86/x86toIR.o
 
 PUB_INCLUDES = -Ipub
@@ -97,4 +98,8 @@ priv/host-generic/reg_alloc.o: $(ALL_HEADERS) priv/host-generic/reg_alloc.c
 
 priv/guest-x86/x86toIR.o: $(ALL_HEADERS) priv/guest-x86/x86toIR.c
        $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest-x86/x86toIR.o \
-                                        -c priv/guest-x86/x86toIR.c
\ No newline at end of file
+                                        -c priv/guest-x86/x86toIR.c
+
+priv/guest-x86/x86helpers.o: $(ALL_HEADERS) priv/guest-x86/x86helpers.c
+       $(CC) $(CCFLAGS) $(ALL_INCLUDES) -o priv/guest-x86/x86helpers.o \
+                                        -c priv/guest-x86/x86helpers.c
index 55cf44778905e85751b320f655d4d7d545b9b48b..2baa51ce8dfaaf371894a7043235c1cd9f3885dc 100644 (file)
@@ -26,6 +26,11 @@ 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
+Addr64 x86guest_findhelper ( Char* function_name );
+
 
 /*---------------------------------------------------------*/
 /*--- Condition code stuff                              ---*/
diff --git a/VEX/priv/guest-x86/x86helpers.c b/VEX/priv/guest-x86/x86helpers.c
new file mode 100644 (file)
index 0000000..ed25937
--- /dev/null
@@ -0,0 +1,62 @@
+
+/*---------------------------------------------------------------*/
+/*---                                                         ---*/
+/*--- This file (x86helpers.c) is                             ---*/
+/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
+/*---                                                         ---*/
+/*---------------------------------------------------------------*/
+
+#include "libvex_basictypes.h"
+#include "libvex_ir.h"
+#include "vex_util.h"
+#include "x86guest_defs.h"
+
+/* This file contains helper functions for x86 guest code.
+   Calls to these functions are generated by the back end.
+   These calls are of course in the host machine code and 
+   this file will be compiled to host machine code, so that
+   all makes sense.  
+
+   x86guest_findhelper() is the only exported function. 
+
+   Only change the signatures of these helper functions very
+   carefully.  If you change the signature here, you'll have to change
+   the parameters passed to it in the IR calls constructed by
+   x86toIR.c.  
+*/
+
+
+/* RUNS AS PART OF GENERATED CODE */
+static UInt calculate_eflags_all ( UInt cc_op, UInt cc_src, UInt cc_dst )
+{
+   switch (cc_op) {
+      default:
+         /* shouldn't really make these calls from generated code */
+         vex_printf("calculate_eflags_all: unhandled %d\n", cc_op);
+         vpanic("calculate_eflags_all");
+   }
+}
+
+/* RUNS AS PART OF GENERATED CODE */
+static UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
+{
+   return calculate_eflags_all(cc_op,cc_src,cc_dst) & CC_MASK_C;
+}
+
+
+/* The only exported function. */
+
+Addr64 x86guest_findhelper ( Char* function_name )
+{
+   if (vex_streq(function_name, "calculate_eflags_all"))
+      return (Addr64)(& calculate_eflags_all);
+   if (vex_streq(function_name, "calculate_eflags_c"))
+      return (Addr64)(& calculate_eflags_c);
+   vex_printf("\nx86 guest: can't find helper: %s\n", function_name);
+   vpanic("x86guest_findhelper");
+}
+
+
+/*---------------------------------------------------------------*/
+/*--- end                                        x86helpers.c ---*/
+/*---------------------------------------------------------------*/
index b6a8177630271cc3d5ddc4d20ee2ba40c548ce74..5ae49d0b108fd6c1e7e6c715880a0bb154426bdb 100644 (file)
@@ -135,6 +135,8 @@ static IRExpr* bind ( Int binder )
 
 /* This carries around:
 
+   - A function for looking up the address of 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.
@@ -159,6 +161,8 @@ static IRExpr* bind ( Int binder )
 
 typedef
    struct {
+      Addr64       (*find_helper)(Char*);
+
       IRTypeEnv*   type_env;
 
       HReg*        vregmap;
@@ -411,8 +415,9 @@ static HReg iselIntExpr_R ( ISelEnv* env, IRExpr* e )
 
    /* --------- CCALL --------- */
    case Iex_CCall: {
-      Int i, nargs;
-      UInt target;
+      Addr64 helper;
+      Int    i, nargs;
+      UInt   target;
       IRExpr* arg;
       vassert(ty == Ity_I32);
       /* be very restrictive for now.  Only 32-bit ints allowed
@@ -428,7 +433,12 @@ static HReg iselIntExpr_R ( ISelEnv* env, IRExpr* e )
             goto irreducible;
          addInstr(env, X86Instr_Push(iselIntExpr_RMI(env, arg)));
       }
-      target = 0x12345678; //FIND_HELPER(e->Iex.CCall.name);
+      /* Find the function to call.  Since the host -- for which we
+         are generating code -- is a 32-bit machine (x86) -- the upper
+         32 bit of the helper address should be zero. */
+      helper = env->find_helper(e->Iex.CCall.name);
+      vassert((helper & 0xFFFFFFFF00000000LL) == 0);
+      target = helper & 0xFFFFFFFF;
       addInstr(env, X86Instr_Alu32R(
                        Xalu_MOV,
                        X86RMI_Imm(target),
@@ -905,7 +915,7 @@ static void iselNext ( ISelEnv* env, IRExpr* next, IRJumpKind jk )
 
 /* Translate an entire BB to x86 code. */
 
-HInstrArray* iselBB_X86 ( IRBB* bb )
+HInstrArray* iselBB_X86 ( IRBB* bb, Addr64(*find_helper)(Char*) )
 {
    Int     i, j;
    HReg    hreg, hregHI;
@@ -915,6 +925,9 @@ HInstrArray* iselBB_X86 ( IRBB* bb )
    ISelEnv* env = LibVEX_Alloc(sizeof(ISelEnv));
    env->vreg_ctr = 0;
 
+   /* Register helper-function-finder. */
+   env->find_helper = find_helper;
+
    /* Set up output code array. */
    env->code = newHInstrArray();
 
index 6ddd0cde9531784c291656c9b435f0dd49ec668f..84d1c8dfc23395f24d917e7bbe7aaf006349347c 100644 (file)
@@ -670,7 +670,7 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
       case Xin_Call:
          addHRegUse(u, HRmRead, i->Xin.Call.target);
          /* claim it trashes all the callee-saved regs */
-         /* except I have no idea what they are */
+         /* which I believe to be %eax,%ecx,%edx. */
          addHRegUse(u, HRmWrite, hregX86_EAX());
          addHRegUse(u, HRmWrite, hregX86_ECX());
          addHRegUse(u, HRmWrite, hregX86_EDX());
@@ -1341,6 +1341,7 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i )
 }
 
 
+#if 0
 /* Self-contained test; can be called directly from
    main. */
 void test_asm86 ( void )
@@ -1427,7 +1428,7 @@ T( X86Instr_Alu32M(Xalu_SUB, X86RI_Reg(ecx), X86AMode_IR(0x7F,ebp)) );
 
 #undef T
 }
-
+#endif
 
 
 /*---------------------------------------------------------------*/
index c48716bdca0ca3deea3447970bb7661ca85493cf..08013770069394b4745525150b7da368e0ab5d12 100644 (file)
@@ -375,7 +375,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* );
+extern HInstrArray* iselBB_X86           ( IRBB*, Addr64(*)(Char*) );
 
 #endif /* ndef __LIBVEX_X86H_DEFS_H */
 
index 3e92d91a3eda7ea657af7b70156c3aba6ec43630..656e768135424e569885cafbc613755cf41298aa 100644 (file)
@@ -91,10 +91,11 @@ TranslateResult LibVEX_Translate (
    HInstr*      (*genReload)   ( HReg, Int );
    void         (*ppInstr)     ( HInstr* );
    void         (*ppReg)       ( HReg );
-   HInstrArray* (*iselBB)      ( IRBB* );
+   HInstrArray* (*iselBB)      ( IRBB*, Addr64(*)(Char*) );
    IRBB*        (*bbToIR)      ( UChar*, Addr64, Int*, 
                                          Bool(*)(Addr64), Bool );
    Int          (*emit)        ( UChar*, Int, HInstr* );
+   Addr64       (*findHelper)  ( Char* );
 
    Bool         host_is_bigendian = False;
    IRBB*        irbb;
@@ -103,6 +104,20 @@ TranslateResult LibVEX_Translate (
    Int          i, j, k, out_used;
    UChar        insn_bytes[32];
 
+   available_real_regs    = NULL;
+   n_available_real_regs  = 0;
+   isMove                 = NULL;
+   getRegUsage            = NULL;
+   mapRegs                = NULL;
+   genSpill               = NULL;
+   genReload              = NULL;
+   ppInstr                = NULL;
+   ppReg                  = NULL;
+   iselBB                 = NULL;
+   bbToIR                 = NULL;
+   emit                   = NULL;
+   findHelper             = NULL;
+
    vassert(vex_initdone);
    LibVEX_ClearTemporary(False);
 
@@ -129,7 +144,8 @@ TranslateResult LibVEX_Translate (
 
    switch (iset_guest) {
       case InsnSetX86:
-         bbToIR = bbToIR_X86Instr;
+         bbToIR     = bbToIR_X86Instr;
+         findHelper = x86guest_findhelper;
          break;
       default:
          vpanic("LibVEX_Translate: unsupported guest insn set");
@@ -153,7 +169,7 @@ TranslateResult LibVEX_Translate (
       irbb = (*instrument)(irbb);
 
    /* Turn it into virtual-registerised code. */
-   vcode = iselBB ( irbb );
+   vcode = iselBB ( irbb, findHelper );
 
    if (vex_verbosity > 0) {
       vex_printf("\n-------- Virtual registerised code --------\n");
index 98f41c30a0945a5b0647d9642ae8825e056ea55c..601176bb234af024c4cc7d88801f56255cbfbfd9 100644 (file)
@@ -168,6 +168,17 @@ static Int vex_strlen ( const Char* str )
    return i;
 }
 
+Bool vex_streq ( const Char* s1, const Char* s2 )
+{
+   while (True) {
+      if (*s1 == 0 && *s2 == 0)
+         return True;
+      if (*s1 != *s2)
+         return False;
+      s1++;
+      s2++;
+   }
+}
 
 /* Some flags.  */
 #define VG_MSG_SIGNED    1 /* The value is signed. */
index 97ffe9cdfeba0377737ee96680f5e331723868d4..2f1b53abca98fe390bbb095f62df1c2bfedd5063 100644 (file)
@@ -42,6 +42,12 @@ extern UInt vex_printf ( const Char *format, ... );
 __attribute__ ((format (printf, 2, 3)))
 extern UInt vex_sprintf ( Char* buf, const Char *format, ... );
 
+
+/* String ops */
+
+extern Bool vex_streq ( const Char* s1, const Char* s2 );
+
+
 #endif /* ndef __VEX_UTIL_H */
 
 /*---------------------------------------------------------------*/