}
}
+
+/* --------- 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 ---*/
/*---------------------------------------------------------------*/
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** );
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. */
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*);
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);
ppInstr = (void(*)(HInstr*)) ppX86Instr;
ppReg = (void(*)(HReg)) ppHRegX86;
iselBB = iselBB_X86;
+ emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
host_is_bigendian = False;
break;
default:
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);