offset. */
HInstr* (*genSpill) ( HReg, Int ),
HInstr* (*genReload) ( HReg, Int ),
+ Int guest_sizeB,
/* For debug printing only. */
void (*ppInstr) ( HInstr* ),
/* 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,
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;
/* The output array of instructions. */
HInstrArray* instrs_out;
+ vassert(0 == LibVEX_N_SPILL_BYTES % 16);
+ vassert(0 == guest_sizeB % 8);
# define INVALID_INSTRNO (-2)
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; */
}
}
-/* 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:
}
}
-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 );
/*---------------------------------------------------------------*/
#include "libvex.h"
+#include "libvex_guest_x86.h"
#include "main/vex_globals.h"
#include "main/vex_util.h"
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
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;
bbToIR = bbToIR_X86Instr;
findHelper = x86guest_findhelper;
specHelper = x86guest_spechelper;
+ guest_sizeB = sizeof(VexGuestX86State);
break;
default:
vpanic("LibVEX_Translate: unsupported guest insn set");
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) {
extern void LibVEX_ShowStats ( void );
+
+/* A note about baseblock layout.
+
+ LibVEX defines the layout for the guest state, in the file
+ pub/libvex_guest_<arch>.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 */
/*---------------------------------------------------------------*/
UShort guest_FS;
UShort guest_GS;
UShort guest_SS;
+ /* Padding to make it have an 8-aligned size */
+ UInt padding;
}
VexGuestX86State;