]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Arch-abstraction:
authorNicholas Nethercote <n.nethercote@gmail.com>
Mon, 6 Sep 2004 16:43:37 +0000 (16:43 +0000)
committerNicholas Nethercote <n.nethercote@gmail.com>
Mon, 6 Sep 2004 16:43:37 +0000 (16:43 +0000)
- moved a lot of the baseBlock initialisation into x86/, including all the
  VGOFF variables, and all the x86 asm helper functions.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2668

coregrind/core.h
coregrind/vg_main.c
coregrind/x86/core_arch.h
coregrind/x86/state.c
include/tool.h.base
include/x86/tool_arch.h

index 51467ad96e4ed8b1f4601d3822beac1056726f02..e51242d0c8ba8f2fcaa69db4b4600e2b077f231b 100644 (file)
@@ -1280,6 +1280,10 @@ extern UInt VG_(unchained_jumps_done); // Number of unchained jumps performed
 
 extern void VG_(print_scheduler_stats) ( void );
 
+extern Int  VG_(alloc_BaB)( Int );      // Allocate slots in baseBlock
+extern void VG_(align_BaB)( UInt );     // Align baseBlock offset
+extern Int  VG_(alloc_BaB_1_set)( Addr ); // Allocate & init baseBlock slot
+
 /* ---------------------------------------------------------------------
    Exports of vg_memory.c
    ------------------------------------------------------------------ */
@@ -1446,57 +1450,6 @@ extern UInt VG_(patch_me);
    Exports of vg_helpers.S
    ------------------------------------------------------------------ */
 
-/* Mul, div, etc, -- we don't codegen these directly. */
-extern void VG_(helper_idiv_64_32);
-extern void VG_(helper_div_64_32);
-extern void VG_(helper_idiv_32_16);
-extern void VG_(helper_div_32_16);
-extern void VG_(helper_idiv_16_8);
-extern void VG_(helper_div_16_8);
-
-extern void VG_(helper_imul_32_64);
-extern void VG_(helper_mul_32_64);
-extern void VG_(helper_imul_16_32);
-extern void VG_(helper_mul_16_32);
-extern void VG_(helper_imul_8_16);
-extern void VG_(helper_mul_8_16);
-
-extern void VG_(helper_CLD);
-extern void VG_(helper_STD);
-extern void VG_(helper_get_dirflag);
-
-extern void VG_(helper_CLC);
-extern void VG_(helper_STC);
-extern void VG_(helper_CMC);
-
-extern void VG_(helper_shldl);
-extern void VG_(helper_shldw);
-extern void VG_(helper_shrdl);
-extern void VG_(helper_shrdw);
-
-extern void VG_(helper_IN);
-extern void VG_(helper_OUT);
-
-extern void VG_(helper_RDTSC);
-extern void VG_(helper_CPUID);
-
-extern void VG_(helper_bsfw);
-extern void VG_(helper_bsfl);
-extern void VG_(helper_bsrw);
-extern void VG_(helper_bsrl);
-
-extern void VG_(helper_fstsw_AX);
-extern void VG_(helper_SAHF);
-extern void VG_(helper_LAHF);
-extern void VG_(helper_DAS);
-extern void VG_(helper_DAA);
-extern void VG_(helper_AAS);
-extern void VG_(helper_AAA);
-extern void VG_(helper_AAD);
-extern void VG_(helper_AAM);
-
-extern void VG_(helper_cmpxchg8b);
-
 extern void VG_(helper_undefined_instruction);
 
 /* Information about trampoline code (for signal return and syscalls) */
@@ -1522,12 +1475,7 @@ extern void VG_(missing_tool_func) ( const Char* fn );
    The state of the simulated CPU.
    ------------------------------------------------------------------ */
 
-/* ---------------------------------------------------------------------
-   Offsets into baseBlock for everything which needs to referred to
-   from generated code.  The order of these decls does not imply 
-   what the order of the actual offsets is.  The latter is important
-   and is set up in vg_main.c.
-   ------------------------------------------------------------------ */
+#define INVALID_OFFSET (-1)
 
 /* An array of words.  In generated code, %ebp always points to the
    start of this array.  Useful stuff, like the simulated CPU state,
@@ -1540,64 +1488,14 @@ extern void VG_(missing_tool_func) ( const Char* fn );
 
 extern UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
 
-/* -----------------------------------------------------
-   Read-write parts of baseBlock.
-   -------------------------------------------------- */
-
-/* State of the simulated CPU. */
-extern Int VGOFF_(m_eax);
-extern Int VGOFF_(m_ecx);
-extern Int VGOFF_(m_edx);
-extern Int VGOFF_(m_ebx);
-extern Int VGOFF_(m_esp);
-extern Int VGOFF_(m_ebp);
-extern Int VGOFF_(m_esi);
-extern Int VGOFF_(m_edi);
-extern Int VGOFF_(m_eflags);
-extern Int VGOFF_(m_ssestate);
-extern Int VGOFF_(m_eip);
-
-extern Int VGOFF_(m_dflag);    /* D flag is handled specially */
-
-extern Int VGOFF_(m_cs);
-extern Int VGOFF_(m_ss);
-extern Int VGOFF_(m_ds);
-extern Int VGOFF_(m_es);
-extern Int VGOFF_(m_fs);
-extern Int VGOFF_(m_gs);
-
-/* Reg-alloc spill area (VG_MAX_SPILLSLOTS words long). */
-extern Int VGOFF_(spillslots);
-
-/* Records the valid bits for the 8 integer regs & flags reg. */
-extern Int VGOFF_(sh_eax);
-extern Int VGOFF_(sh_ecx);
-extern Int VGOFF_(sh_edx);
-extern Int VGOFF_(sh_ebx);
-extern Int VGOFF_(sh_esp);
-extern Int VGOFF_(sh_ebp);
-extern Int VGOFF_(sh_esi);
-extern Int VGOFF_(sh_edi);
-extern Int VGOFF_(sh_eflags);
-
-/* -----------------------------------------------------
-   Read-only parts of baseBlock.
-   -------------------------------------------------- */
-
-/* This thread's LDT pointer. */
-extern Int VGOFF_(ldt);
-
-/* This thread's TLS pointer. */
-extern Int VGOFF_(tls_ptr);
-
-/* Nb: Most helper offsets are in include/tool.h, for use by tools */
-
-extern Int VGOFF_(helper_undefined_instruction);
-
 // ---------------------------------------------------------------------
 // Architecture-specific things defined in eg. x86/*.c
 // ---------------------------------------------------------------------
 
+/* For setting up the baseBlock */    
+extern void VGA_(init_low_baseBlock)  ( Addr client_eip, Addr esp_at_startup );
+extern void VGA_(init_high_baseBlock) ( Addr client_eip, Addr esp_at_startup );
+
 extern void VGA_(load_state) ( arch_thread_t*, ThreadId tid );
 extern void VGA_(save_state) ( arch_thread_t*, ThreadId tid );
 
index adff5c50f123208f896964263aae02aab8dc866c..0f2063cd41c83b75c4ba2086f00a2725a3bdd8cc 100644 (file)
@@ -2107,82 +2107,6 @@ static void setup_file_descriptors(void)
 /*=== baseBlock: definition + setup                                ===*/
 /*====================================================================*/
 
-/* The variables storing offsets. */
-
-#define INVALID_OFFSET (-1)
-
-Int VGOFF_(m_eax) = INVALID_OFFSET;
-Int VGOFF_(m_ecx) = INVALID_OFFSET;
-Int VGOFF_(m_edx) = INVALID_OFFSET;
-Int VGOFF_(m_ebx) = INVALID_OFFSET;
-Int VGOFF_(m_esp) = INVALID_OFFSET;
-Int VGOFF_(m_ebp) = INVALID_OFFSET;
-Int VGOFF_(m_esi) = INVALID_OFFSET;
-Int VGOFF_(m_edi) = INVALID_OFFSET;
-Int VGOFF_(m_eflags) = INVALID_OFFSET;
-Int VGOFF_(m_dflag)  = INVALID_OFFSET;
-Int VGOFF_(m_ssestate) = INVALID_OFFSET;
-Int VGOFF_(ldt)   = INVALID_OFFSET;
-Int VGOFF_(tls_ptr) = INVALID_OFFSET;
-Int VGOFF_(m_cs)  = INVALID_OFFSET;
-Int VGOFF_(m_ss)  = INVALID_OFFSET;
-Int VGOFF_(m_ds)  = INVALID_OFFSET;
-Int VGOFF_(m_es)  = INVALID_OFFSET;
-Int VGOFF_(m_fs)  = INVALID_OFFSET;
-Int VGOFF_(m_gs)  = INVALID_OFFSET;
-Int VGOFF_(m_eip) = INVALID_OFFSET;
-Int VGOFF_(spillslots) = INVALID_OFFSET;
-Int VGOFF_(sh_eax) = INVALID_OFFSET;
-Int VGOFF_(sh_ecx) = INVALID_OFFSET;
-Int VGOFF_(sh_edx) = INVALID_OFFSET;
-Int VGOFF_(sh_ebx) = INVALID_OFFSET;
-Int VGOFF_(sh_esp) = INVALID_OFFSET;
-Int VGOFF_(sh_ebp) = INVALID_OFFSET;
-Int VGOFF_(sh_esi) = INVALID_OFFSET;
-Int VGOFF_(sh_edi) = INVALID_OFFSET;
-Int VGOFF_(sh_eflags) = INVALID_OFFSET;
-
-Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
-Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
-Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
-Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
-Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
-Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
-Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
-Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
-Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
-Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
-Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
-Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
-Int VGOFF_(helper_CLD) = INVALID_OFFSET;
-Int VGOFF_(helper_STD) = INVALID_OFFSET;
-Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
-Int VGOFF_(helper_CLC) = INVALID_OFFSET;
-Int VGOFF_(helper_STC) = INVALID_OFFSET;
-Int VGOFF_(helper_CMC) = INVALID_OFFSET;
-Int VGOFF_(helper_shldl) = INVALID_OFFSET;
-Int VGOFF_(helper_shldw) = INVALID_OFFSET;
-Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
-Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
-Int VGOFF_(helper_IN) = INVALID_OFFSET;
-Int VGOFF_(helper_OUT) = INVALID_OFFSET;
-Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
-Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
-Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
-Int VGOFF_(helper_bsfw) = INVALID_OFFSET;
-Int VGOFF_(helper_bsfl) = INVALID_OFFSET;
-Int VGOFF_(helper_bsrw) = INVALID_OFFSET;
-Int VGOFF_(helper_bsrl) = INVALID_OFFSET;
-Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
-Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
-Int VGOFF_(helper_LAHF) = INVALID_OFFSET;
-Int VGOFF_(helper_DAS) = INVALID_OFFSET;
-Int VGOFF_(helper_DAA) = INVALID_OFFSET;
-Int VGOFF_(helper_AAS) = INVALID_OFFSET;
-Int VGOFF_(helper_AAA) = INVALID_OFFSET;
-Int VGOFF_(helper_AAD) = INVALID_OFFSET;
-Int VGOFF_(helper_AAM) = INVALID_OFFSET;
-Int VGOFF_(helper_cmpxchg8b) = INVALID_OFFSET;
 Int VGOFF_(helper_undefined_instruction) = INVALID_OFFSET;
 
 /* MAX_NONCOMPACT_HELPERS can be increased easily.  If MAX_COMPACT_HELPERS is
@@ -2210,18 +2134,18 @@ static Int baB_off = 0;
 
 
 /* Returns the offset, in words. */
-static Int alloc_BaB ( Int words )
+Int VG_(alloc_BaB) ( Int words )
 {
    Int off = baB_off;
    baB_off += words;
    if (baB_off >= VG_BASEBLOCK_WORDS)
-      VG_(core_panic)( "alloc_BaB: baseBlock is too small");
+      VG_(core_panic)( "VG_(alloc_BaB): baseBlock is too small");
 
    return off;   
 }
 
 /* Align offset, in *bytes* */
-static void align_BaB ( UInt align )
+void VG_(align_BaB) ( UInt align )
 {
    vg_assert(2 == align || 4 == align || 8 == align || 16 == align);
    baB_off +=  (align-1);
@@ -2229,9 +2153,9 @@ static void align_BaB ( UInt align )
 }
 
 /* Allocate 1 word in baseBlock and set it to the given value. */
-static Int alloc_BaB_1_set ( Addr a )
+Int VG_(alloc_BaB_1_set) ( Addr a )
 {
-   Int off = alloc_BaB(1);
+   Int off = VG_(alloc_BaB)(1);
    VG_(baseBlock)[off] = (UInt)a;
    return off;
 }
@@ -2270,7 +2194,7 @@ void assign_helpers_in_baseBlock(UInt n, Int offsets[], Addr addrs[])
 {
    UInt i;
    for (i = 0; i < n; i++) 
-      offsets[i] = alloc_BaB_1_set( addrs[i] );
+      offsets[i] = VG_(alloc_BaB_1_set)( addrs[i] );
 }
 
 Bool VG_(need_to_handle_esp_assignment)(void)
@@ -2290,133 +2214,19 @@ Bool VG_(need_to_handle_esp_assignment)(void)
           );
 }
 
-/* Here we assign actual offsets.  It's important to get the most
-   popular referents within 128 bytes of the start, so we can take
-   advantage of short addressing modes relative to %ebp.  Popularity
-   of offsets was measured on 22 Feb 02 running a KDE application, and
-   the slots rearranged accordingly, with a 1.5% reduction in total
-   size of translations. */
+// The low/high split is for x86, so that the more common helpers can be
+// in the first 128 bytes of the start, which allows the use of a more
+// compact addressing mode.
 static void init_baseBlock ( Addr client_eip, Addr esp_at_startup )
 {
-   /* Those with offsets under 128 are carefully chosen. */
-
-   /* WORD offsets in this column */
-   /* 0   */ VGOFF_(m_eax)     = alloc_BaB_1_set(0);
-   /* 1   */ VGOFF_(m_ecx)     = alloc_BaB_1_set(0);
-   /* 2   */ VGOFF_(m_edx)     = alloc_BaB_1_set(0);
-   /* 3   */ VGOFF_(m_ebx)     = alloc_BaB_1_set(0);
-   /* 4   */ VGOFF_(m_esp)     = alloc_BaB_1_set(esp_at_startup);
-   /* 5   */ VGOFF_(m_ebp)     = alloc_BaB_1_set(0);
-   /* 6   */ VGOFF_(m_esi)     = alloc_BaB_1_set(0);
-   /* 7   */ VGOFF_(m_edi)     = alloc_BaB_1_set(0);
-   /* 8   */ VGOFF_(m_eflags)  = alloc_BaB_1_set(0);
-
-   if (VG_(needs).shadow_regs) {
-      /* 9   */ VGOFF_(sh_eax)    = alloc_BaB_1_set(0);
-      /* 10  */ VGOFF_(sh_ecx)    = alloc_BaB_1_set(0);
-      /* 11  */ VGOFF_(sh_edx)    = alloc_BaB_1_set(0);
-      /* 12  */ VGOFF_(sh_ebx)    = alloc_BaB_1_set(0);
-      /* 13  */ VGOFF_(sh_esp)    = alloc_BaB_1_set(0);
-      /* 14  */ VGOFF_(sh_ebp)    = alloc_BaB_1_set(0);
-      /* 15  */ VGOFF_(sh_esi)    = alloc_BaB_1_set(0);
-      /* 16  */ VGOFF_(sh_edi)    = alloc_BaB_1_set(0);
-      /* 17  */ VGOFF_(sh_eflags) = alloc_BaB_1_set(0);
-      VG_TRACK( post_regs_write_init );
-   }
-
-   /* 9,10,11 or 18,19,20... depends on number whether shadow regs are used
-    * and on compact helpers registered */ 
-
-   /* Make these most-frequently-called specialised ones compact, if they
-      are used. */
-   if (VG_(defined_new_mem_stack_4)())
-      VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_new_mem_stack_4);
-
-   if (VG_(defined_die_mem_stack_4)())
-      VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_die_mem_stack_4);
-
-   /* (9 or 18) + n_compact_helpers  */
+   VGA_(init_low_baseBlock)(client_eip, esp_at_startup);
+
    /* Allocate slots for compact helpers */
    assign_helpers_in_baseBlock(VG_(n_compact_helpers), 
                                VG_(compact_helper_offsets), 
                                VG_(compact_helper_addrs));
 
-   /* (9/10 or 18/19) + n_compact_helpers */
-   VGOFF_(m_eip) = alloc_BaB_1_set(client_eip);
-
-   /* There are currently 24 spill slots */
-   /* (11+/20+ .. 32+/43+) + n_compact_helpers.  This can overlap the magic
-    * boundary at >= 32 words, but most spills are to low numbered spill
-    * slots, so the ones above the boundary don't see much action. */
-   VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
-
-   /* I gave up counting at this point.  Since they're above the
-      short-amode-boundary, there's no point. */
-
-   VGOFF_(m_dflag) = alloc_BaB_1_set(1);  // 1 == forward D-flag
-
-   /* The FPU/SSE state.  This _must_ be 16-byte aligned.  Initial
-      state doesn't matter much, as long as it's not totally borked. */
-   align_BaB(16);
-   VGOFF_(m_ssestate) = alloc_BaB(VG_SIZE_OF_SSESTATE_W);
-   vg_assert( 
-      0 == ( ((UInt)(& VG_(baseBlock)[VGOFF_(m_ssestate)])) % 16 )
-   );
-
-   /* I assume that if we have SSE2 we also have SSE */
-   VG_(have_ssestate) = 
-          VG_(cpu_has_feature)(VG_X86_FEAT_FXSR) &&
-          VG_(cpu_has_feature)(VG_X86_FEAT_SSE);
-
-   /* set up an initial FPU state (doesn't really matter what it is,
-      so long as it's somewhat valid) */
-   if (!VG_(have_ssestate))
-      asm volatile("fwait; fnsave %0; fwait; frstor %0; fwait" 
-                   : 
-                   : "m" (VG_(baseBlock)[VGOFF_(m_ssestate)]) 
-                   : "cc", "memory");
-   else
-      asm volatile("fwait; fxsave %0; fwait; andl $0xffbf, %1;"
-                   "fxrstor %0; fwait"
-                   : 
-                   : "m" (VG_(baseBlock)[VGOFF_(m_ssestate)]), 
-                     "m" (VG_(baseBlock)[VGOFF_(m_ssestate)+(24/4)]) 
-                   : "cc", "memory");
-
-   if (0) {
-      if (VG_(have_ssestate))
-         VG_(printf)("Looks like a SSE-capable CPU\n");
-      else
-         VG_(printf)("Looks like a MMX-only CPU\n");
-   }
-
-   /* LDT pointer: pretend the root thread has an empty LDT to start with. */
-   VGOFF_(ldt)   = alloc_BaB_1_set((UInt)NULL);
-
-   /* TLS pointer: pretend the root thread has no TLS array for now. */
-   VGOFF_(tls_ptr) = alloc_BaB_1_set((UInt)NULL);
-
-   /* segment registers */
-   VGOFF_(m_cs)  = alloc_BaB_1_set(0);
-   VGOFF_(m_ss)  = alloc_BaB_1_set(0);
-   VGOFF_(m_ds)  = alloc_BaB_1_set(0);
-   VGOFF_(m_es)  = alloc_BaB_1_set(0);
-   VGOFF_(m_fs)  = alloc_BaB_1_set(0);
-   VGOFF_(m_gs)  = alloc_BaB_1_set(0);
-
-   /* initialise %cs, %ds and %ss to point at the operating systems
-      default code, data and stack segments */
-   asm volatile("movw %%cs, %0"
-                :
-                : "m" (VG_(baseBlock)[VGOFF_(m_cs)]));
-   asm volatile("movw %%ds, %0"
-                :
-                : "m" (VG_(baseBlock)[VGOFF_(m_ds)]));
-   asm volatile("movw %%ss, %0"
-                :
-                : "m" (VG_(baseBlock)[VGOFF_(m_ss)]));
-
-   VG_(register_noncompact_helper)( (Addr) & VG_(do_useseg) );
+   VGA_(init_high_baseBlock)(client_eip, esp_at_startup);
 
 #define REG(kind, size) \
    if (VG_(defined_##kind##_mem_stack##size)()) \
@@ -2437,43 +2247,8 @@ static void init_baseBlock ( Addr client_eip, Addr esp_at_startup )
    if (VG_(need_to_handle_esp_assignment)())
       VG_(register_noncompact_helper)((Addr) VG_(unknown_esp_update));
 
-#  define HELPER(name) \
-   VGOFF_(helper_##name) = alloc_BaB_1_set( (Addr) & VG_(helper_##name))
-
-   /* Helper functions. */
-   HELPER(idiv_64_32);     HELPER(div_64_32);
-   HELPER(idiv_32_16);     HELPER(div_32_16);
-   HELPER(idiv_16_8);      HELPER(div_16_8);
-
-   HELPER(imul_32_64);     HELPER(mul_32_64);
-   HELPER(imul_16_32);     HELPER(mul_16_32);
-   HELPER(imul_8_16);      HELPER(mul_8_16);
-
-   HELPER(CLD);            HELPER(STD);
-   HELPER(get_dirflag);
-
-   HELPER(CLC);            HELPER(STC);
-   HELPER(CMC);
-
-   HELPER(shldl);          HELPER(shldw);
-   HELPER(shrdl);          HELPER(shrdw);
-
-   HELPER(RDTSC);          HELPER(CPUID);
-
-   HELPER(bsfw);           HELPER(bsfl);
-   HELPER(bsrw);           HELPER(bsrl);
-
-   HELPER(fstsw_AX);
-   HELPER(SAHF);           HELPER(LAHF);
-   HELPER(DAS);            HELPER(DAA);
-   HELPER(AAS);            HELPER(AAA);
-   HELPER(AAD);            HELPER(AAM);
-   HELPER(IN);             HELPER(OUT);
-   HELPER(cmpxchg8b);
-
-   HELPER(undefined_instruction);
-
-#  undef HELPER
+   VGOFF_(helper_undefined_instruction)
+      = VG_(alloc_BaB_1_set)( (Addr) & VG_(helper_undefined_instruction));
 
    /* Allocate slots for noncompact helpers */
    assign_helpers_in_baseBlock(VG_(n_noncompact_helpers), 
index 2039ee69b8d9c7fd80ca5c3314470952d07087df..55fae1945b67ddf9b7fb78d6c050ca2a9d5e2e44 100644 (file)
 #define VGOFF_STACK_PTR                VGOFF_(m_esp)
 #define VGOFF_FRAME_PTR                VGOFF_(m_ebp)
 
+/* -----------------------------------------------------
+   Read-write parts of baseBlock.
+   -------------------------------------------------- */
+
+/* State of the simulated CPU. */
+extern Int VGOFF_(m_eax);
+extern Int VGOFF_(m_ecx);
+extern Int VGOFF_(m_edx);
+extern Int VGOFF_(m_ebx);
+extern Int VGOFF_(m_esp);
+extern Int VGOFF_(m_ebp);
+extern Int VGOFF_(m_esi);
+extern Int VGOFF_(m_edi);
+extern Int VGOFF_(m_eflags);
+extern Int VGOFF_(m_ssestate);
+extern Int VGOFF_(m_eip);
+
+extern Int VGOFF_(m_dflag);    /* D flag is handled specially */
+
+extern Int VGOFF_(m_cs);
+extern Int VGOFF_(m_ss);
+extern Int VGOFF_(m_ds);
+extern Int VGOFF_(m_es);
+extern Int VGOFF_(m_fs);
+extern Int VGOFF_(m_gs);
+
+/* Reg-alloc spill area (VG_MAX_SPILLSLOTS words long). */
+extern Int VGOFF_(spillslots);
+
+/* Records the valid bits for the 8 integer regs & flags reg. */
+extern Int VGOFF_(sh_eax);
+extern Int VGOFF_(sh_ecx);
+extern Int VGOFF_(sh_edx);
+extern Int VGOFF_(sh_ebx);
+extern Int VGOFF_(sh_esp);
+extern Int VGOFF_(sh_ebp);
+extern Int VGOFF_(sh_esi);
+extern Int VGOFF_(sh_edi);
+extern Int VGOFF_(sh_eflags);
+
+/* -----------------------------------------------------
+   Read-only parts of baseBlock.
+   -------------------------------------------------- */
+
+/* This thread's LDT pointer. */
+extern Int VGOFF_(ldt);
+
+/* This thread's TLS pointer. */
+extern Int VGOFF_(tls_ptr);
+
+/* Nb: Most helper offsets are in include/tool.h, for use by tools */
+extern Int VGOFF_(helper_undefined_instruction);
+
+
+/* ---------------------------------------------------------------------
+   Exports of vg_helpers.S
+   ------------------------------------------------------------------ */
+
+/* Mul, div, etc, -- we don't codegen these directly. */
+extern void VG_(helper_idiv_64_32);
+extern void VG_(helper_div_64_32);
+extern void VG_(helper_idiv_32_16);
+extern void VG_(helper_div_32_16);
+extern void VG_(helper_idiv_16_8);
+extern void VG_(helper_div_16_8);
+
+extern void VG_(helper_imul_32_64);
+extern void VG_(helper_mul_32_64);
+extern void VG_(helper_imul_16_32);
+extern void VG_(helper_mul_16_32);
+extern void VG_(helper_imul_8_16);
+extern void VG_(helper_mul_8_16);
+
+extern void VG_(helper_CLD);
+extern void VG_(helper_STD);
+extern void VG_(helper_get_dirflag);
+
+extern void VG_(helper_CLC);
+extern void VG_(helper_STC);
+extern void VG_(helper_CMC);
+
+extern void VG_(helper_shldl);
+extern void VG_(helper_shldw);
+extern void VG_(helper_shrdl);
+extern void VG_(helper_shrdw);
+
+extern void VG_(helper_IN);
+extern void VG_(helper_OUT);
+
+extern void VG_(helper_RDTSC);
+extern void VG_(helper_CPUID);
+
+extern void VG_(helper_bsfw);
+extern void VG_(helper_bsfl);
+extern void VG_(helper_bsrw);
+extern void VG_(helper_bsrl);
+
+extern void VG_(helper_fstsw_AX);
+extern void VG_(helper_SAHF);
+extern void VG_(helper_LAHF);
+extern void VG_(helper_DAS);
+extern void VG_(helper_DAA);
+extern void VG_(helper_AAS);
+extern void VG_(helper_AAA);
+extern void VG_(helper_AAD);
+extern void VG_(helper_AAM);
+
+extern void VG_(helper_cmpxchg8b);
 
 /* ---------------------------------------------------------------------
    Exports of vg_ldt.c
index a27e9bcb4356ebcd1bb1c30a1852d2af8df9ba8e..ab47351d1842128f320f8b2ab7278491ee551287 100644 (file)
 
 #include "core.h"
 
+/*------------------------------------------------------------*/
+/*--- baseBlock setup                                      ---*/
+/*------------------------------------------------------------*/
+
+/* The variables storing offsets. */
+
+Int VGOFF_(m_eax) = INVALID_OFFSET;
+Int VGOFF_(m_ecx) = INVALID_OFFSET;
+Int VGOFF_(m_edx) = INVALID_OFFSET;
+Int VGOFF_(m_ebx) = INVALID_OFFSET;
+Int VGOFF_(m_esp) = INVALID_OFFSET;
+Int VGOFF_(m_ebp) = INVALID_OFFSET;
+Int VGOFF_(m_esi) = INVALID_OFFSET;
+Int VGOFF_(m_edi) = INVALID_OFFSET;
+Int VGOFF_(m_eflags) = INVALID_OFFSET;
+Int VGOFF_(m_dflag)  = INVALID_OFFSET;
+Int VGOFF_(m_ssestate) = INVALID_OFFSET;
+Int VGOFF_(ldt)   = INVALID_OFFSET;
+Int VGOFF_(tls_ptr) = INVALID_OFFSET;
+Int VGOFF_(m_cs)  = INVALID_OFFSET;
+Int VGOFF_(m_ss)  = INVALID_OFFSET;
+Int VGOFF_(m_ds)  = INVALID_OFFSET;
+Int VGOFF_(m_es)  = INVALID_OFFSET;
+Int VGOFF_(m_fs)  = INVALID_OFFSET;
+Int VGOFF_(m_gs)  = INVALID_OFFSET;
+Int VGOFF_(m_eip) = INVALID_OFFSET;
+Int VGOFF_(spillslots) = INVALID_OFFSET;
+Int VGOFF_(sh_eax) = INVALID_OFFSET;
+Int VGOFF_(sh_ecx) = INVALID_OFFSET;
+Int VGOFF_(sh_edx) = INVALID_OFFSET;
+Int VGOFF_(sh_ebx) = INVALID_OFFSET;
+Int VGOFF_(sh_esp) = INVALID_OFFSET;
+Int VGOFF_(sh_ebp) = INVALID_OFFSET;
+Int VGOFF_(sh_esi) = INVALID_OFFSET;
+Int VGOFF_(sh_edi) = INVALID_OFFSET;
+Int VGOFF_(sh_eflags) = INVALID_OFFSET;
+
+Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
+Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
+Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
+Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
+Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
+Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
+Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
+Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
+Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
+Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
+Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
+Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
+Int VGOFF_(helper_CLD) = INVALID_OFFSET;
+Int VGOFF_(helper_STD) = INVALID_OFFSET;
+Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
+Int VGOFF_(helper_CLC) = INVALID_OFFSET;
+Int VGOFF_(helper_STC) = INVALID_OFFSET;
+Int VGOFF_(helper_CMC) = INVALID_OFFSET;
+Int VGOFF_(helper_shldl) = INVALID_OFFSET;
+Int VGOFF_(helper_shldw) = INVALID_OFFSET;
+Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
+Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
+Int VGOFF_(helper_IN) = INVALID_OFFSET;
+Int VGOFF_(helper_OUT) = INVALID_OFFSET;
+Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
+Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
+Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
+Int VGOFF_(helper_bsfw) = INVALID_OFFSET;
+Int VGOFF_(helper_bsfl) = INVALID_OFFSET;
+Int VGOFF_(helper_bsrw) = INVALID_OFFSET;
+Int VGOFF_(helper_bsrl) = INVALID_OFFSET;
+Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
+Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
+Int VGOFF_(helper_LAHF) = INVALID_OFFSET;
+Int VGOFF_(helper_DAS) = INVALID_OFFSET;
+Int VGOFF_(helper_DAA) = INVALID_OFFSET;
+Int VGOFF_(helper_AAS) = INVALID_OFFSET;
+Int VGOFF_(helper_AAA) = INVALID_OFFSET;
+Int VGOFF_(helper_AAD) = INVALID_OFFSET;
+Int VGOFF_(helper_AAM) = INVALID_OFFSET;
+Int VGOFF_(helper_cmpxchg8b) = INVALID_OFFSET;
+
 static Int extractDflag(UInt eflags)
 {
    return ( eflags & EFlagD ? -1 : 1 );
@@ -43,6 +122,170 @@ static UInt insertDflag(UInt eflags, Int d)
    return eflags;
 }
 
+/* Here we assign actual offsets.  It's important on x86 to get the most
+   popular referents within 128 bytes of the start, so we can take
+   advantage of short addressing modes relative to %ebp.  Popularity
+   of offsets was measured on 22 Feb 02 running a KDE application, and
+   the slots rearranged accordingly, with a 1.5% reduction in total
+   size of translations. */
+void VGA_(init_low_baseBlock) ( Addr client_eip, Addr esp_at_startup )
+{
+   /* Those with offsets under 128 are carefully chosen. */
+
+   /* WORD offsets in this column */
+   /* 0   */ VGOFF_(m_eax)     = VG_(alloc_BaB_1_set)(0);
+   /* 1   */ VGOFF_(m_ecx)     = VG_(alloc_BaB_1_set)(0);
+   /* 2   */ VGOFF_(m_edx)     = VG_(alloc_BaB_1_set)(0);
+   /* 3   */ VGOFF_(m_ebx)     = VG_(alloc_BaB_1_set)(0);
+   /* 4   */ VGOFF_(m_esp)     = VG_(alloc_BaB_1_set)(esp_at_startup);
+   /* 5   */ VGOFF_(m_ebp)     = VG_(alloc_BaB_1_set)(0);
+   /* 6   */ VGOFF_(m_esi)     = VG_(alloc_BaB_1_set)(0);
+   /* 7   */ VGOFF_(m_edi)     = VG_(alloc_BaB_1_set)(0);
+   /* 8   */ VGOFF_(m_eflags)  = VG_(alloc_BaB_1_set)(0);
+
+   if (VG_(needs).shadow_regs) {
+      /* 9   */ VGOFF_(sh_eax)    = VG_(alloc_BaB_1_set)(0);
+      /* 10  */ VGOFF_(sh_ecx)    = VG_(alloc_BaB_1_set)(0);
+      /* 11  */ VGOFF_(sh_edx)    = VG_(alloc_BaB_1_set)(0);
+      /* 12  */ VGOFF_(sh_ebx)    = VG_(alloc_BaB_1_set)(0);
+      /* 13  */ VGOFF_(sh_esp)    = VG_(alloc_BaB_1_set)(0);
+      /* 14  */ VGOFF_(sh_ebp)    = VG_(alloc_BaB_1_set)(0);
+      /* 15  */ VGOFF_(sh_esi)    = VG_(alloc_BaB_1_set)(0);
+      /* 16  */ VGOFF_(sh_edi)    = VG_(alloc_BaB_1_set)(0);
+      /* 17  */ VGOFF_(sh_eflags) = VG_(alloc_BaB_1_set)(0);
+      VG_TRACK( post_regs_write_init );
+   }
+
+   /* 9,10,11 or 18,19,20... depends on number whether shadow regs are used
+    * and on compact helpers registered */ 
+
+   /* Make these most-frequently-called specialised ones compact, if they
+      are used. */
+   if (VG_(defined_new_mem_stack_4)())
+      VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_new_mem_stack_4);
+
+   if (VG_(defined_die_mem_stack_4)())
+      VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_die_mem_stack_4);
+
+}
+
+void VGA_(init_high_baseBlock)( Addr client_eip, Addr esp_at_startup )
+{
+   /* (9/10 or 18/19) + n_compact_helpers */
+   VGOFF_(m_eip) = VG_(alloc_BaB_1_set)(client_eip);
+
+   /* There are currently 24 spill slots */
+   /* (11+/20+ .. 32+/43+) + n_compact_helpers.  This can overlap the magic
+    * boundary at >= 32 words, but most spills are to low numbered spill
+    * slots, so the ones above the boundary don't see much action. */
+   VGOFF_(spillslots) = VG_(alloc_BaB)(VG_MAX_SPILLSLOTS);
+
+   /* I gave up counting at this point.  Since they're above the
+      short-amode-boundary, there's no point. */
+
+   VGOFF_(m_dflag) = VG_(alloc_BaB_1_set)(1);  // 1 == forward D-flag
+
+   /* The FPU/SSE state.  This _must_ be 16-byte aligned.  Initial
+      state doesn't matter much, as long as it's not totally borked. */
+   VG_(align_BaB)(16);
+   VGOFF_(m_ssestate) = VG_(alloc_BaB)(VG_SIZE_OF_SSESTATE_W);
+   vg_assert( 
+      0 == ( ((UInt)(& VG_(baseBlock)[VGOFF_(m_ssestate)])) % 16 )
+   );
+
+   /* I assume that if we have SSE2 we also have SSE */
+   VG_(have_ssestate) = 
+          VG_(cpu_has_feature)(VG_X86_FEAT_FXSR) &&
+          VG_(cpu_has_feature)(VG_X86_FEAT_SSE);
+
+   /* set up an initial FPU state (doesn't really matter what it is,
+      so long as it's somewhat valid) */
+   if (!VG_(have_ssestate))
+      asm volatile("fwait; fnsave %0; fwait; frstor %0; fwait" 
+                   : 
+                   : "m" (VG_(baseBlock)[VGOFF_(m_ssestate)]) 
+                   : "cc", "memory");
+   else
+      asm volatile("fwait; fxsave %0; fwait; andl $0xffbf, %1;"
+                   "fxrstor %0; fwait"
+                   : 
+                   : "m" (VG_(baseBlock)[VGOFF_(m_ssestate)]), 
+                     "m" (VG_(baseBlock)[VGOFF_(m_ssestate)+(24/4)]) 
+                   : "cc", "memory");
+
+   if (0) {
+      if (VG_(have_ssestate))
+         VG_(printf)("Looks like a SSE-capable CPU\n");
+      else
+         VG_(printf)("Looks like a MMX-only CPU\n");
+   }
+
+   /* LDT pointer: pretend the root thread has an empty LDT to start with. */
+   VGOFF_(ldt)   = VG_(alloc_BaB_1_set)((UInt)NULL);
+
+   /* TLS pointer: pretend the root thread has no TLS array for now. */
+   VGOFF_(tls_ptr) = VG_(alloc_BaB_1_set)((UInt)NULL);
+
+   /* segment registers */
+   VGOFF_(m_cs)  = VG_(alloc_BaB_1_set)(0);
+   VGOFF_(m_ss)  = VG_(alloc_BaB_1_set)(0);
+   VGOFF_(m_ds)  = VG_(alloc_BaB_1_set)(0);
+   VGOFF_(m_es)  = VG_(alloc_BaB_1_set)(0);
+   VGOFF_(m_fs)  = VG_(alloc_BaB_1_set)(0);
+   VGOFF_(m_gs)  = VG_(alloc_BaB_1_set)(0);
+
+   /* initialise %cs, %ds and %ss to point at the operating systems
+      default code, data and stack segments */
+   asm volatile("movw %%cs, %0"
+                :
+                : "m" (VG_(baseBlock)[VGOFF_(m_cs)]));
+   asm volatile("movw %%ds, %0"
+                :
+                : "m" (VG_(baseBlock)[VGOFF_(m_ds)]));
+   asm volatile("movw %%ss, %0"
+                :
+                : "m" (VG_(baseBlock)[VGOFF_(m_ss)]));
+
+   VG_(register_noncompact_helper)( (Addr) & VG_(do_useseg) );
+
+#  define HELPER(name) \
+   VGOFF_(helper_##name) = VG_(alloc_BaB_1_set)( (Addr) & VG_(helper_##name))
+
+   /* Helper functions. */
+   HELPER(idiv_64_32);     HELPER(div_64_32);
+   HELPER(idiv_32_16);     HELPER(div_32_16);
+   HELPER(idiv_16_8);      HELPER(div_16_8);
+
+   HELPER(imul_32_64);     HELPER(mul_32_64);
+   HELPER(imul_16_32);     HELPER(mul_16_32);
+   HELPER(imul_8_16);      HELPER(mul_8_16);
+
+   HELPER(CLD);            HELPER(STD);
+   HELPER(get_dirflag);
+
+   HELPER(CLC);            HELPER(STC);
+   HELPER(CMC);
+
+   HELPER(shldl);          HELPER(shldw);
+   HELPER(shrdl);          HELPER(shrdw);
+
+   HELPER(RDTSC);          HELPER(CPUID);
+
+   HELPER(bsfw);           HELPER(bsfl);
+   HELPER(bsrw);           HELPER(bsrl);
+
+   HELPER(fstsw_AX);
+   HELPER(SAHF);           HELPER(LAHF);
+   HELPER(DAS);            HELPER(DAA);
+   HELPER(AAS);            HELPER(AAA);
+   HELPER(AAD);            HELPER(AAM);
+   HELPER(IN);             HELPER(OUT);
+   HELPER(cmpxchg8b);
+
+   HELPER(undefined_instruction);
+
+#  undef HELPER
+}
 
 /* Junk to fill up a thread's shadow regs with when shadow regs aren't
    being used. */
index 2402957081aaf203509c92b0876aabc399a9a795..01585bb70a7208947892f2b447385d98e603e30a 100644 (file)
 #include <setjmp.h>       /* for jmp_buf         */
 
 #include "tool_asm.h"           // asm stuff
+
+/*====================================================================*/
+/*=== Basic types                                                  ===*/
+/*====================================================================*/
+
+typedef unsigned char          UChar;
+typedef unsigned short         UShort;
+typedef unsigned int           UInt;
+typedef unsigned long long int ULong;
+
+typedef signed char            Char;
+typedef signed short           Short;
+typedef signed int             Int;
+typedef signed long long int   Long;
+
+typedef unsigned int           Addr;
+
+typedef unsigned char          Bool;
+#define False                  ((Bool)0)
+#define True                   ((Bool)1)
+
+/* ---------------------------------------------------------------------
+   Now the basic types are set up, we can haul in the kernel-interface
+   definitions and tool_arch.h
+   ------------------------------------------------------------------ */
+
 #include "tool_arch.h"          // arch-specific tool stuff
+#include "vg_kerneliface.h"
 
 /* ---------------------------------------------------------------------
    Where to send bug reports to.
 
 
 /*====================================================================*/
-/*=== Basic types, useful macros                                   ===*/
+/*=== Useful macros                                                ===*/
 /*====================================================================*/
 
-typedef unsigned char          UChar;
-typedef unsigned short         UShort;
-typedef unsigned int           UInt;
-typedef unsigned long long int ULong;
-
-typedef signed char            Char;
-typedef signed short           Short;
-typedef signed int             Int;
-typedef signed long long int   Long;
-
-typedef unsigned int           Addr;
-
-typedef unsigned char          Bool;
-#define False                  ((Bool)0)
-#define True                   ((Bool)1)
-
-
 #define mycat_wrk(aaa,bbb) aaa##bbb
 #define mycat(aaa,bbb) mycat_wrk(aaa,bbb)
 
 /* No, really.  I _am_ that strange. */
 #define OINK(nnn) VG_(message)(Vg_DebugMsg, "OINK %d",nnn)
 
-/* ---------------------------------------------------------------------
-   Now the basic types are set up, we can haul in the kernel-interface
-   definitions.
-   ------------------------------------------------------------------ */
-
-#include "vg_kerneliface.h"
-
-
 /* Path to all our library/aux files */
 extern const Char *VG_(libdir);
 
@@ -1248,61 +1250,6 @@ extern UInt VG_(get_thread_shadow_archreg) ( ThreadId tid, UInt archreg );
 extern void VG_(set_thread_shadow_archreg) ( ThreadId tid, UInt archreg,
                                              UInt val );
 
-/* ------------------------------------------------------------------ */
-/* Offsets of addresses of helper functions.  A "helper" function is one
-   which is called from generated code via CALLM. */
-
-extern Int VGOFF_(helper_idiv_64_32);
-extern Int VGOFF_(helper_div_64_32);
-extern Int VGOFF_(helper_idiv_32_16);
-extern Int VGOFF_(helper_div_32_16);
-extern Int VGOFF_(helper_idiv_16_8);
-extern Int VGOFF_(helper_div_16_8);
-
-extern Int VGOFF_(helper_imul_32_64);
-extern Int VGOFF_(helper_mul_32_64);
-extern Int VGOFF_(helper_imul_16_32);
-extern Int VGOFF_(helper_mul_16_32);
-extern Int VGOFF_(helper_imul_8_16);
-extern Int VGOFF_(helper_mul_8_16);
-
-extern Int VGOFF_(helper_CLD);
-extern Int VGOFF_(helper_STD);
-extern Int VGOFF_(helper_get_dirflag);
-
-extern Int VGOFF_(helper_CLC);
-extern Int VGOFF_(helper_STC);
-extern Int VGOFF_(helper_CMC);
-
-extern Int VGOFF_(helper_shldl);
-extern Int VGOFF_(helper_shldw);
-extern Int VGOFF_(helper_shrdl);
-extern Int VGOFF_(helper_shrdw);
-
-extern Int VGOFF_(helper_RDTSC);
-extern Int VGOFF_(helper_CPUID);
-
-extern Int VGOFF_(helper_IN);
-extern Int VGOFF_(helper_OUT);
-
-extern Int VGOFF_(helper_bsfw);
-extern Int VGOFF_(helper_bsfl);
-extern Int VGOFF_(helper_bsrw);
-extern Int VGOFF_(helper_bsrl);
-
-extern Int VGOFF_(helper_fstsw_AX);
-extern Int VGOFF_(helper_SAHF);
-extern Int VGOFF_(helper_LAHF);
-extern Int VGOFF_(helper_DAS);
-extern Int VGOFF_(helper_DAA);
-extern Int VGOFF_(helper_AAS);
-extern Int VGOFF_(helper_AAA);
-extern Int VGOFF_(helper_AAD);
-extern Int VGOFF_(helper_AAM);
-
-extern Int VGOFF_(helper_cmpxchg8b);
-
-
 /*====================================================================*/
 /*=== Generating x86 code from UCode                               ===*/
 /*====================================================================*/
index 272e2fa3947da6fd04e0a40b42925257e72af98f..96e8a7a7d0dfbd9615df0b8bd6a79a456c860b8a 100644 (file)
 #ifndef __X86_TOOL_ARCH_H
 #define __X86_TOOL_ARCH_H
 
+// XXX: eventually a lot of the stuff in this file can be made private to
+// the x86/ subdir, and not visible to the core.  But as long as the core
+// still refers to them, they'll have to stay in here.
+
+/*====================================================================*/
+/*=== Registers, etc                                               ===*/
+/*====================================================================*/
+
 #define REGPARM(n)      __attribute__((regparm(n)))
 
 #define FIRST_ARCH_REG  R_EAX
 #define MIN_INSTR_SIZE     1
 #define MAX_INSTR_SIZE    16
 
+
+/*====================================================================*/
+/*=== Instrumenting UCode                                          ===*/
+/*====================================================================*/
+
+/* ------------------------------------------------------------------ */
+/* Offsets of addresses of helper functions.  A "helper" function is one
+   which is called from generated code via CALLM. */
+
+// XXX: eventually these should be private to the x86 part, not visible to
+// tools, and the IR should provide a better way than this to see what the
+// original instruction was.
+
+extern Int VGOFF_(helper_idiv_64_32);
+extern Int VGOFF_(helper_div_64_32);
+extern Int VGOFF_(helper_idiv_32_16);
+extern Int VGOFF_(helper_div_32_16);
+extern Int VGOFF_(helper_idiv_16_8);
+extern Int VGOFF_(helper_div_16_8);
+
+extern Int VGOFF_(helper_imul_32_64);
+extern Int VGOFF_(helper_mul_32_64);
+extern Int VGOFF_(helper_imul_16_32);
+extern Int VGOFF_(helper_mul_16_32);
+extern Int VGOFF_(helper_imul_8_16);
+extern Int VGOFF_(helper_mul_8_16);
+
+extern Int VGOFF_(helper_CLD);
+extern Int VGOFF_(helper_STD);
+extern Int VGOFF_(helper_get_dirflag);
+
+extern Int VGOFF_(helper_CLC);
+extern Int VGOFF_(helper_STC);
+extern Int VGOFF_(helper_CMC);
+
+extern Int VGOFF_(helper_shldl);
+extern Int VGOFF_(helper_shldw);
+extern Int VGOFF_(helper_shrdl);
+extern Int VGOFF_(helper_shrdw);
+
+extern Int VGOFF_(helper_RDTSC);
+extern Int VGOFF_(helper_CPUID);
+
+extern Int VGOFF_(helper_IN);
+extern Int VGOFF_(helper_OUT);
+
+extern Int VGOFF_(helper_bsfw);
+extern Int VGOFF_(helper_bsfl);
+extern Int VGOFF_(helper_bsrw);
+extern Int VGOFF_(helper_bsrl);
+
+extern Int VGOFF_(helper_fstsw_AX);
+extern Int VGOFF_(helper_SAHF);
+extern Int VGOFF_(helper_LAHF);
+extern Int VGOFF_(helper_DAS);
+extern Int VGOFF_(helper_DAA);
+extern Int VGOFF_(helper_AAS);
+extern Int VGOFF_(helper_AAA);
+extern Int VGOFF_(helper_AAD);
+extern Int VGOFF_(helper_AAM);
+
+extern Int VGOFF_(helper_cmpxchg8b);
+
+
 #endif   // __X86_TOOL_ARCH_H
 
 /*--------------------------------------------------------------------*/