From: Julian Seward Date: Wed, 21 Jul 2004 18:49:27 +0000 (+0000) Subject: Assembler infrastructure. X-Git-Tag: svn/VALGRIND_3_0_1^2~1235 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f114050fba95ed0c7efe70dd64baae5b3caaf22f;p=thirdparty%2Fvalgrind.git Assembler infrastructure. git-svn-id: svn://svn.valgrind.org/vex/trunk@99 --- diff --git a/VEX/priv/host-x86/x86h_defs.c b/VEX/priv/host-x86/x86h_defs.c index ff75e69c4d..8eb751da25 100644 --- a/VEX/priv/host-x86/x86h_defs.c +++ b/VEX/priv/host-x86/x86h_defs.c @@ -782,6 +782,23 @@ X86Instr* genReload_X86 ( HReg rreg, Int offset ) } } + +/* --------- The x86 assembler (bleh.) --------- */ + +/* Emit an instruction into buf and return the number of bytes used. + Note that buf is not the insn's final place, and therefore it is + imperative to emit position-independent code. */ + +Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) +{ + switch (i->tag) { + default: + ppX86Instr(i); + vpanic("emit_X86Instr"); + } +} + + /*---------------------------------------------------------------*/ /*--- end x86h_defs.c ---*/ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/host-x86/x86h_defs.h b/VEX/priv/host-x86/x86h_defs.h index 39d28a5092..3714083194 100644 --- a/VEX/priv/host-x86/x86h_defs.h +++ b/VEX/priv/host-x86/x86h_defs.h @@ -366,6 +366,7 @@ extern void ppX86Instr ( X86Instr* ); extern void getRegUsage_X86Instr ( HRegUsage*, X86Instr* ); extern void mapRegs_X86Instr ( HRegRemap*, X86Instr* ); extern Bool isMove_X86Instr ( X86Instr*, HReg*, HReg* ); +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** ); diff --git a/VEX/priv/main/vex_main.c b/VEX/priv/main/vex_main.c index cac3f77383..ee7b8b0219 100644 --- a/VEX/priv/main/vex_main.c +++ b/VEX/priv/main/vex_main.c @@ -64,13 +64,13 @@ TranslateResult LibVEX_Translate ( InsnSet iset_guest, InsnSet iset_host, /* IN: the block to translate, and its guest address. */ - Char* guest_bytes, + UChar* guest_bytes, Addr64 guest_bytes_addr, /* OUT: the number of bytes actually read */ Int* guest_bytes_read, /* IN: a place to put the resulting code, and its size */ - Char* host_bytes, - Int host_bytes_size, + UChar* host_bytes, + Int host_bytes_size, /* OUT: how much of the output area is used. */ Int* host_bytes_used, /* IN: optionally, an instrumentation function. */ @@ -79,7 +79,9 @@ TranslateResult LibVEX_Translate ( Bool (*byte_accessible) ( Addr64 ) ) { - /* Stuff we need to know for reg-alloc. */ + /* This the bundle of functions we need to do the back-end stuff + (insn selection, reg-alloc, assembly) whilst being insulated + from the target instruction set. */ HReg* available_real_regs; Int n_available_real_regs; Bool (*isMove) (HInstr*, HReg*, HReg*); @@ -92,12 +94,13 @@ TranslateResult LibVEX_Translate ( HInstrArray* (*iselBB) ( IRBB* ); IRBB* (*bbToIR) ( UChar*, Addr64, Int*, Bool(*)(Addr64), Bool ); + Int (*emit) ( UChar*, Int, HInstr* ); Bool host_is_bigendian = False; IRBB* irbb; HInstrArray* vcode; HInstrArray* rcode; - Int i; + Int i, j, k, out_used; vassert(vex_initdone); LibVEX_ClearTemporary(False); @@ -116,6 +119,7 @@ TranslateResult LibVEX_Translate ( ppInstr = (void(*)(HInstr*)) ppX86Instr; ppReg = (void(*)(HReg)) ppHRegX86; iselBB = iselBB_X86; + emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr; host_is_bigendian = False; break; default: @@ -177,7 +181,23 @@ TranslateResult LibVEX_Translate ( vex_printf("\n"); } - /* Assemble, etc. */ + /* Assemble */ + UChar insn_bytes[32]; + out_used = 0; /* tracks along the host_bytes array */ + for (i = 0; i < rcode->arr_used; i++) { + j = (*emit)( insn_bytes, 32, rcode->arr[i] ); + if (out_used + j > host_bytes_size) { + LibVEX_ClearTemporary(False); + return TransOutputFull; + } + for (k = 0; k < j; k++) { + host_bytes[out_used] = insn_bytes[k]; + out_used++; + } + vassert(out_used <= host_bytes_size); + } + *host_bytes_used = out_used; + // LibVEX_ClearTemporary(True); LibVEX_ClearTemporary(False); diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 7468fa2b59..e771f2dea3 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -72,13 +72,13 @@ TranslateResult LibVEX_Translate ( InsnSet iset_guest, InsnSet iset_host, /* IN: the block to translate, and its guest address. */ - Char* guest_bytes, + UChar* guest_bytes, Addr64 guest_bytes_addr, /* OUT: the number of bytes actually read */ Int* guest_bytes_read, /* IN: a place to put the resulting code, and its size */ - Char* host_bytes, - Int host_bytes_size, + UChar* host_bytes, + Int host_bytes_size, /* OUT: how much of the output area is used. */ Int* host_bytes_used, /* IN: optionally, an instrumentation function. */ diff --git a/VEX/test_main.c b/VEX/test_main.c index f5ed09f2ac..5c4d8e1c3f 100644 --- a/VEX/test_main.c +++ b/VEX/test_main.c @@ -96,7 +96,7 @@ int main ( int argc, char** argv ) } // if (bb_number == 50) exit(1); - { int i; + { for (i = 0; i < 1; i++) tres = LibVEX_Translate ( InsnSetX86, InsnSetX86,