From: Julian Seward Date: Mon, 25 Oct 2004 23:15:52 +0000 (+0000) Subject: New regime for baseblock layout, as described in comment in X-Git-Tag: svn/VALGRIND_3_0_1^2~908 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7fa3982f87b0cd60ff5d52dc36f1b65ac9d63dd3;p=thirdparty%2Fvalgrind.git New regime for baseblock layout, as described in comment in pub/libvex.h. Now the client has to go along with LibVEX's baseblock layout decisions and is essentially powerless to make its own decisions on the matter. git-svn-id: svn://svn.valgrind.org/vex/trunk@426 --- diff --git a/VEX/priv/host-generic/h_generic_regs.h b/VEX/priv/host-generic/h_generic_regs.h index b6d7151a81..6f33491828 100644 --- a/VEX/priv/host-generic/h_generic_regs.h +++ b/VEX/priv/host-generic/h_generic_regs.h @@ -218,6 +218,7 @@ HInstrArray* doRegisterAllocation ( offset. */ HInstr* (*genSpill) ( HReg, Int ), HInstr* (*genReload) ( HReg, Int ), + Int guest_sizeB, /* For debug printing only. */ void (*ppInstr) ( HInstr* ), diff --git a/VEX/priv/host-generic/reg_alloc.c b/VEX/priv/host-generic/reg_alloc.c index e67eb60406..420edc15cf 100644 --- a/VEX/priv/host-generic/reg_alloc.c +++ b/VEX/priv/host-generic/reg_alloc.c @@ -15,9 +15,6 @@ /* Set to 1 for lots of debugging output. */ #define DEBUG_REGALLOC 0 -/* How many 64-bit sized spill slots do we have? */ -#define N_SPILL64S 50 - /* TODO (critical) - Need a way to statically establish the vreg classes, @@ -201,15 +198,18 @@ HInstrArray* doRegisterAllocation ( void (*mapRegs) (HRegRemap*, HInstr*), /* Return an insn to spill/restore a real reg to a spill slot - offset. */ + byte offset. */ HInstr* (*genSpill) ( HReg, Int ), HInstr* (*genReload) ( HReg, Int ), + Int guest_sizeB, /* For debug printing only. */ void (*ppInstr) ( HInstr* ), void (*ppReg) ( HReg ) ) { +# define N_SPILL64S (LibVEX_N_SPILL_BYTES / 8) + /* Iterators and temporaries. */ Int ii, j, k, m, spillee; HReg rreg, vreg, vregS, vregD; @@ -242,6 +242,8 @@ HInstrArray* doRegisterAllocation ( /* The output array of instructions. */ HInstrArray* instrs_out; + vassert(0 == LibVEX_N_SPILL_BYTES % 16); + vassert(0 == guest_sizeB % 8); # define INVALID_INSTRNO (-2) @@ -550,10 +552,15 @@ HInstrArray* doRegisterAllocation ( if (ss_busy_until_before[k] <= vreg_info[j].live_after) break; if (k == N_SPILL64S) { - vpanic("N_SPILL64S is too low"); + vpanic("LibVEX_N_SPILL_BYTES is too low. Increase and recompile."); } ss_busy_until_before[k] = vreg_info[j].dead_before; - vreg_info[j].spill_offset = k * 8; + + /* This reflects LibVEX's hard-wired knowledge of the baseBlock + layout: the guest state, then an equal sized area following + it for shadow state, and then the spill area. */ + vreg_info[j].spill_offset = guest_sizeB * 2 + k * 8; + /* if (j > max_ss_no) */ /* max_ss_no = j; */ } diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index 382c7f51f1..81935ad5ba 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -1073,18 +1073,15 @@ Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst ) } -/* x86 spill/reload using the hacked104 testbed. Spill slots - start at word 55, and there are 100 in total. -*/ +/* Generate x86 spill/reload instructions under the direction of the + register allocator. */ -X86Instr* genSpill_X86 ( HReg rreg, Int offset ) +X86Instr* genSpill_X86 ( HReg rreg, Int offsetB ) { X86AMode* am; - Int base = 4 * 37; - vassert(offset >= 0); - vassert(offset <= 4*(100-1)); + vassert(offsetB >= 0); vassert(!hregIsVirtual(rreg)); - am = X86AMode_IR(offset + base, hregX86_EBP()); + am = X86AMode_IR(offsetB, hregX86_EBP()); switch (hregClass(rreg)) { case HRcInt: @@ -1097,14 +1094,12 @@ X86Instr* genSpill_X86 ( HReg rreg, Int offset ) } } -X86Instr* genReload_X86 ( HReg rreg, Int offset ) +X86Instr* genReload_X86 ( HReg rreg, Int offsetB ) { X86AMode* am; - Int base = 4 * 37; - vassert(offset >= 0); - vassert(offset <= 4*(100-1)); + vassert(offsetB >= 0); vassert(!hregIsVirtual(rreg)); - am = X86AMode_IR(offset + base, hregX86_EBP()); + am = X86AMode_IR(offsetB, hregX86_EBP()); switch (hregClass(rreg)) { case HRcInt: return X86Instr_Alu32R ( Xalu_MOV, X86RMI_Mem(am), rreg ); diff --git a/VEX/priv/main/vex_main.c b/VEX/priv/main/vex_main.c index a9861463cc..8f60330841 100644 --- a/VEX/priv/main/vex_main.c +++ b/VEX/priv/main/vex_main.c @@ -7,6 +7,7 @@ /*---------------------------------------------------------------*/ #include "libvex.h" +#include "libvex_guest_x86.h" #include "main/vex_globals.h" #include "main/vex_util.h" @@ -73,6 +74,9 @@ void LibVEX_Init ( vassert(vcon->guest_chase_thresh >= 0); vassert(vcon->guest_chase_thresh < vcon->guest_max_insns); + /* All the guest state structs must have an 8-aligned size. */ + vassert(0 == sizeof(VexGuestX86State) % 8); + /* Check that Vex has been built with sizes of basic types as stated in priv/libvex_basictypes.h. Failure of any of these is a serious configuration error and should be corrected @@ -157,7 +161,7 @@ TranslateResult LibVEX_Translate ( IRBB* irbb; HInstrArray* vcode; HInstrArray* rcode; - Int i, j, k, out_used, saved_verbosity; + Int i, j, k, out_used, saved_verbosity, guest_sizeB; UChar insn_bytes[32]; available_real_regs = NULL; @@ -210,6 +214,7 @@ TranslateResult LibVEX_Translate ( bbToIR = bbToIR_X86Instr; findHelper = x86guest_findhelper; specHelper = x86guest_spechelper; + guest_sizeB = sizeof(VexGuestX86State); break; default: vpanic("LibVEX_Translate: unsupported guest insn set"); @@ -273,7 +278,7 @@ TranslateResult LibVEX_Translate ( rcode = doRegisterAllocation ( vcode, available_real_regs, n_available_real_regs, isMove, getRegUsage, mapRegs, - genSpill, genReload, + genSpill, genReload, guest_sizeB, ppInstr, ppReg ); if (vex_verbosity > 0) { diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 60a889570a..d36783c382 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -130,6 +130,23 @@ TranslateResult LibVEX_Translate ( extern void LibVEX_ShowStats ( void ); + +/* A note about baseblock layout. + + LibVEX defines the layout for the guest state, in the file + pub/libvex_guest_.h. The struct will have an 8-aligned size. + Each translated bb is assumed to be entered with a specified + register pointing at such a struct. Beyond that is a shadow + state area with the same size as the struct. Beyond that is + a spill area that LibVEX may spill into. It must have size + LibVEX_N_SPILL_BYTES, and this will be a 16-aligned number. + + On entry, the baseblock pointer register must be 8-aligned. +*/ + +#define LibVEX_N_SPILL_BYTES 256 + + #endif /* ndef __LIBVEX_H */ /*---------------------------------------------------------------*/ diff --git a/VEX/pub/libvex_guest_x86.h b/VEX/pub/libvex_guest_x86.h index 0afaf3ef8c..7b683bb0fa 100644 --- a/VEX/pub/libvex_guest_x86.h +++ b/VEX/pub/libvex_guest_x86.h @@ -102,6 +102,8 @@ typedef UShort guest_FS; UShort guest_GS; UShort guest_SS; + /* Padding to make it have an 8-aligned size */ + UInt padding; } VexGuestX86State;