#include "libvex.h"
#include "libvex_trc_values.h"
-//.. #include "main/vex_util.h"
-//.. #include "host-generic/h_generic_regs.h"
-//.. #include "host-x86/hdefs.h"
-//..
-//..
-//.. /* --------- Registers. --------- */
-//..
-//.. void ppHRegX86 ( HReg reg )
-//.. {
+#include "main/vex_util.h"
+#include "host-generic/h_generic_regs.h"
+#include "host-amd64/hdefs.h"
+
+
+/* --------- Registers. --------- */
+
+void ppHRegAMD64 ( HReg reg )
+{ vassert(0);
//.. Int r;
//.. static HChar* ireg32_names[8]
//.. = { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi" };
//.. default:
//.. vpanic("ppHRegX86");
//.. }
-//.. }
-//..
+}
+
//.. HReg hregX86_EAX ( void ) { return mkHReg(0, HRcInt32, False); }
//.. HReg hregX86_ECX ( void ) { return mkHReg(1, HRcInt32, False); }
//.. HReg hregX86_EDX ( void ) { return mkHReg(2, HRcInt32, False); }
//.. HReg hregX86_XMM5 ( void ) { return mkHReg(5, HRcVec128, False); }
//.. HReg hregX86_XMM6 ( void ) { return mkHReg(6, HRcVec128, False); }
//.. HReg hregX86_XMM7 ( void ) { return mkHReg(7, HRcVec128, False); }
-//..
-//..
-//.. void getAllocableRegs_X86 ( Int* nregs, HReg** arr )
-//.. {
+
+
+void getAllocableRegs_AMD64 ( Int* nregs, HReg** arr )
+{ *nregs= 0; *arr=NULL;
//.. *nregs = 20;
//.. *arr = LibVEX_Alloc(*nregs * sizeof(HReg));
//.. (*arr)[0] = hregX86_EAX();
//.. (*arr)[17] = hregX86_XMM5();
//.. (*arr)[18] = hregX86_XMM6();
//.. (*arr)[19] = hregX86_XMM7();
-//.. }
-//..
-//..
+}
+
+
//.. /* --------- Condition codes, Intel encoding. --------- */
//..
//.. HChar* showX86CondCode ( X86CondCode cond )
//.. vassert(order >= 0 && order <= 0xFF);
//.. return i;
//.. }
-//..
-//.. void ppX86Instr ( X86Instr* i ) {
-//.. switch (i->tag) {
+
+void ppAMD64Instr ( AMD64Instr* i )
+{
+ switch (i->tag) {
//.. case Xin_Alu32R:
//.. vex_printf("%sl ", showX86AluOp(i->Xin.Alu32R.op));
//.. ppX86RMI(i->Xin.Alu32R.src);
//.. vex_printf(",");
//.. ppHRegX86(i->Xin.SseShuf.dst);
//.. return;
-//..
-//.. default:
-//.. vpanic("ppX86Instr");
-//.. }
-//.. }
-//..
-//.. /* --------- Helpers for register allocation. --------- */
-//..
-//.. void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i)
-//.. {
-//.. Bool unary;
-//.. initHRegUsage(u);
-//.. switch (i->tag) {
+
+ default:
+ vpanic("ppAMD64Instr");
+ }
+}
+
+/* --------- Helpers for register allocation. --------- */
+
+void getRegUsage_AMD64Instr ( HRegUsage* u, AMD64Instr* i )
+{
+ // Bool unary;
+ initHRegUsage(u);
+ switch (i->tag) {
//.. case Xin_Alu32R:
//.. addRegUsage_X86RMI(u, i->Xin.Alu32R.src);
//.. if (i->Xin.Alu32R.op == Xalu_MOV) {
//.. addHRegUse(u, HRmRead, i->Xin.SseShuf.src);
//.. addHRegUse(u, HRmWrite, i->Xin.SseShuf.dst);
//.. return;
-//.. default:
-//.. ppX86Instr(i);
-//.. vpanic("getRegUsage_X86Instr");
-//.. }
-//.. }
+ default:
+ ppAMD64Instr(i);
+ vpanic("getRegUsage_AMD64Instr");
+ }
+}
//..
//.. /* local helper */
//.. static void mapReg(HRegRemap* m, HReg* r)
//.. {
//.. *r = lookupHRegRemap(m, *r);
//.. }
-//..
-//.. void mapRegs_X86Instr (HRegRemap* m, X86Instr* i)
-//.. {
-//.. switch (i->tag) {
+
+void mapRegs_AMD64Instr ( HRegRemap* m, AMD64Instr* i )
+{
+ switch (i->tag) {
//.. case Xin_Alu32R:
//.. mapRegs_X86RMI(m, i->Xin.Alu32R.src);
//.. mapReg(m, &i->Xin.Alu32R.dst);
//.. mapReg(m, &i->Xin.SseShuf.src);
//.. mapReg(m, &i->Xin.SseShuf.dst);
//.. return;
-//.. default:
-//.. ppX86Instr(i);
-//.. vpanic("mapRegs_X86Instr");
-//.. }
-//.. }
-//..
-//.. /* Figure out if i represents a reg-reg move, and if so assign the
-//.. source and destination to *src and *dst. If in doubt say No. Used
-//.. by the register allocator to do move coalescing.
-//.. */
-//.. Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst )
-//.. {
+ default:
+ ppAMD64Instr(i);
+ vpanic("mapRegs_AMD64Instr");
+ }
+}
+
+/* Figure out if i represents a reg-reg move, and if so assign the
+ source and destination to *src and *dst. If in doubt say No. Used
+ by the register allocator to do move coalescing.
+*/
+Bool isMove_AMD64Instr ( AMD64Instr* i, HReg* src, HReg* dst )
+{
//.. /* Moves between integer regs */
//.. if (i->tag == Xin_Alu32R) {
//.. if (i->Xin.Alu32R.op != Xalu_MOV)
//.. *dst = i->Xin.SseReRg.dst;
//.. return True;
//.. }
-//.. return False;
-//.. }
-//..
-//..
-//.. /* Generate x86 spill/reload instructions under the direction of the
-//.. register allocator. Note it's critical these don't write the
-//.. condition codes. */
-//..
-//.. X86Instr* genSpill_X86 ( HReg rreg, Int offsetB )
-//.. {
+ return False;
+}
+
+
+/* Generate amd64 spill/reload instructions under the direction of the
+ register allocator. Note it's critical these don't write the
+ condition codes. */
+
+AMD64Instr* genSpill_AMD64 ( HReg rreg, Int offsetB )
+{vassert(0);
//.. X86AMode* am;
//.. vassert(offsetB >= 0);
//.. vassert(!hregIsVirtual(rreg));
//.. ppHRegClass(hregClass(rreg));
//.. vpanic("genSpill_X86: unimplemented regclass");
//.. }
-//.. }
-//..
-//.. X86Instr* genReload_X86 ( HReg rreg, Int offsetB )
-//.. {
+}
+
+AMD64Instr* genReload_AMD64 ( HReg rreg, Int offsetB )
+{vassert(0);
//.. X86AMode* am;
//.. vassert(offsetB >= 0);
//.. vassert(!hregIsVirtual(rreg));
//.. ppHRegClass(hregClass(rreg));
//.. vpanic("genReload_X86: unimplemented regclass");
//.. }
-//.. }
-//..
-//..
+}
+
+
//.. /* --------- The x86 assembler (bleh.) --------- */
//..
//.. static UInt iregNo ( HReg r )
//.. }
//.. return p;
//.. }
-//..
-//.. /* 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 )
-//.. {
-//.. UInt irno, opc, opc_rr, subopc_imm, opc_imma, opc_cl, opc_imm, subopc;
+
+/* 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_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i )
+{
+ // UInt irno, opc, opc_rr, subopc_imm, opc_imma, opc_cl, opc_imm, subopc;
//..
//.. UInt xtra;
-//.. UChar* p = &buf[0];
+ UChar* p = &buf[0];
//.. UChar* ptmp;
//.. vassert(nbuf >= 32);
//..
//.. # define fake(_n) mkHReg((_n), HRcInt32, False)
//..
//.. /* vex_printf("asm ");ppX86Instr(i); vex_printf("\n"); */
-//..
-//.. switch (i->tag) {
-//..
+
+ switch (i->tag) {
+
//.. case Xin_Alu32R:
//.. /* Deal specially with MOV */
//.. if (i->Xin.Alu32R.op == Xalu_MOV) {
//.. *p++ = (UChar)(i->Xin.SseShuf.order);
//.. goto done;
//..
-//.. default:
-//.. goto bad;
-//.. }
-//..
-//.. bad:
-//.. ppX86Instr(i);
-//.. vpanic("emit_X86Instr");
-//.. /*NOTREACHED*/
-//..
-//.. done:
-//.. vassert(p - &buf[0] <= 32);
-//.. return p - &buf[0];
-//..
-//.. # undef fake
-//.. }
+ default:
+ goto bad;
+ }
+
+ bad:
+ ppAMD64Instr(i);
+ vpanic("emit_AMD64Instr");
+ /*NOTREACHED*/
+
+ // done:
+ vassert(p - &buf[0] <= 32);
+ return p - &buf[0];
+
+# undef fake
+}
/*---------------------------------------------------------------*/
/*--- end host-amd64/hdefs.c ---*/
#ifndef __LIBVEX_HOST_AMD64_HDEFS_H
#define __LIBVEX_HOST_AMD64_HDEFS_H
-//..
-//.. /* --------- Registers. --------- */
-//..
-//.. /* The usual HReg abstraction. There are 8 real int regs,
-//.. 6 real float regs, and 0 real vector regs.
-//.. */
-//..
-//.. extern void ppHRegX86 ( HReg );
-//..
-//.. extern HReg hregX86_EAX ( void );
-//.. extern HReg hregX86_EBX ( void );
-//.. extern HReg hregX86_ECX ( void );
-//.. extern HReg hregX86_EDX ( void );
-//.. extern HReg hregX86_ESP ( void );
-//.. extern HReg hregX86_EBP ( void );
-//.. extern HReg hregX86_ESI ( void );
-//.. extern HReg hregX86_EDI ( void );
-//..
-//.. extern HReg hregX86_FAKE0 ( void );
-//.. extern HReg hregX86_FAKE1 ( void );
-//.. extern HReg hregX86_FAKE2 ( void );
-//.. extern HReg hregX86_FAKE3 ( void );
-//.. extern HReg hregX86_FAKE4 ( void );
-//.. extern HReg hregX86_FAKE5 ( void );
-//..
-//.. extern HReg hregX86_XMM0 ( void );
-//.. extern HReg hregX86_XMM1 ( void );
-//.. extern HReg hregX86_XMM2 ( void );
-//.. extern HReg hregX86_XMM3 ( void );
-//.. extern HReg hregX86_XMM4 ( void );
-//.. extern HReg hregX86_XMM5 ( void );
-//.. extern HReg hregX86_XMM6 ( void );
-//.. extern HReg hregX86_XMM7 ( void );
-//..
-//..
-//.. /* --------- Condition codes, Intel encoding. --------- */
-//..
-//.. typedef
-//.. enum {
-//.. Xcc_O = 0, /* overflow */
-//.. Xcc_NO = 1, /* no overflow */
-//..
-//.. Xcc_B = 2, /* below */
-//.. Xcc_NB = 3, /* not below */
-//..
-//.. Xcc_Z = 4, /* zero */
-//.. Xcc_NZ = 5, /* not zero */
-//..
-//.. Xcc_BE = 6, /* below or equal */
-//.. Xcc_NBE = 7, /* not below or equal */
-//..
-//.. Xcc_S = 8, /* negative */
-//.. Xcc_NS = 9, /* not negative */
-//..
-//.. Xcc_P = 10, /* parity even */
-//.. Xcc_NP = 11, /* not parity even */
-//..
-//.. Xcc_L = 12, /* jump less */
-//.. Xcc_NL = 13, /* not less */
-//..
-//.. Xcc_LE = 14, /* less or equal */
-//.. Xcc_NLE = 15, /* not less or equal */
-//..
-//.. Xcc_ALWAYS = 16 /* the usual hack */
-//.. }
-//.. X86CondCode;
-//..
-//.. extern HChar* showX86CondCode ( X86CondCode );
-//..
-//..
-//.. /* --------- Memory address expressions (amodes). --------- */
-//..
-//.. typedef
-//.. enum {
-//.. Xam_IR, /* Immediate + Reg */
-//.. Xam_IRRS /* Immediate + Reg1 + (Reg2 << Shift) */
-//.. }
-//.. X86AModeTag;
-//..
-//.. typedef
-//.. struct {
-//.. X86AModeTag tag;
-//.. union {
-//.. struct {
-//.. UInt imm;
-//.. HReg reg;
-//.. } IR;
-//.. struct {
-//.. UInt imm;
-//.. HReg base;
-//.. HReg index;
-//.. Int shift; /* 0, 1, 2 or 3 only */
-//.. } IRRS;
-//.. } Xam;
-//.. }
-//.. X86AMode;
-//..
-//.. extern X86AMode* X86AMode_IR ( UInt, HReg );
-//.. extern X86AMode* X86AMode_IRRS ( UInt, HReg, HReg, Int );
-//..
-//.. extern X86AMode* dopyX86AMode ( X86AMode* );
-//..
-//.. extern void ppX86AMode ( X86AMode* );
-//..
-//..
-//.. /* --------- Operand, which can be reg, immediate or memory. --------- */
-//..
-//.. typedef
-//.. enum {
-//.. Xrmi_Imm,
-//.. Xrmi_Reg,
-//.. Xrmi_Mem
-//.. }
-//.. X86RMITag;
-//..
-//.. typedef
-//.. struct {
-//.. X86RMITag tag;
-//.. union {
-//.. struct {
-//.. UInt imm32;
-//.. } Imm;
-//.. struct {
-//.. HReg reg;
-//.. } Reg;
-//.. struct {
-//.. X86AMode* am;
-//.. } Mem;
-//.. }
-//.. Xrmi;
-//.. }
-//.. X86RMI;
-//..
-//.. extern X86RMI* X86RMI_Imm ( UInt );
-//.. extern X86RMI* X86RMI_Reg ( HReg );
-//.. extern X86RMI* X86RMI_Mem ( X86AMode* );
-//..
-//.. extern void ppX86RMI ( X86RMI* );
-//..
-//..
-//.. /* --------- Operand, which can be reg or immediate only. --------- */
-//..
-//.. typedef
-//.. enum {
-//.. Xri_Imm,
-//.. Xri_Reg
-//.. }
-//.. X86RITag;
-//..
-//.. typedef
-//.. struct {
-//.. X86RITag tag;
-//.. union {
-//.. struct {
-//.. UInt imm32;
-//.. } Imm;
-//.. struct {
-//.. HReg reg;
-//.. } Reg;
-//.. }
-//.. Xri;
-//.. }
-//.. X86RI;
-//..
-//.. extern X86RI* X86RI_Imm ( UInt );
-//.. extern X86RI* X86RI_Reg ( HReg );
-//..
-//.. extern void ppX86RI ( X86RI* );
-//..
-//..
-//.. /* --------- Operand, which can be reg or memory only. --------- */
-//..
-//.. typedef
-//.. enum {
-//.. Xrm_Reg,
-//.. Xrm_Mem
-//.. }
-//.. X86RMTag;
-//..
-//.. typedef
-//.. struct {
-//.. X86RMTag tag;
-//.. union {
-//.. struct {
-//.. HReg reg;
-//.. } Reg;
-//.. struct {
-//.. X86AMode* am;
-//.. } Mem;
-//.. }
-//.. Xrm;
-//.. }
-//.. X86RM;
-//..
-//.. extern X86RM* X86RM_Reg ( HReg );
-//.. extern X86RM* X86RM_Mem ( X86AMode* );
-//..
-//.. extern void ppX86RM ( X86RM* );
-//..
-//..
+
+/* --------- Registers. --------- */
+
+/* The usual HReg abstraction. There are 16 real int regs, 6 real
+ float regs, and 16 real vector regs.
+*/
+
+extern void ppHRegAMD64 ( HReg );
+
+extern HReg hregAMD64_RAX ( void );
+extern HReg hregAMD64_RBX ( void );
+extern HReg hregAMD64_RCX ( void );
+extern HReg hregAMD64_RDX ( void );
+extern HReg hregAMD64_RSP ( void );
+extern HReg hregAMD64_RBP ( void );
+extern HReg hregAMD64_RSI ( void );
+extern HReg hregAMD64_RDI ( void );
+extern HReg hregAMD64_R8 ( void );
+extern HReg hregAMD64_R9 ( void );
+extern HReg hregAMD64_R10 ( void );
+extern HReg hregAMD64_R11 ( void );
+extern HReg hregAMD64_R12 ( void );
+extern HReg hregAMD64_R13 ( void );
+extern HReg hregAMD64_R14 ( void );
+extern HReg hregAMD64_R15 ( void );
+
+extern HReg hregAMD64_FAKE0 ( void );
+extern HReg hregAMD64_FAKE1 ( void );
+extern HReg hregAMD64_FAKE2 ( void );
+extern HReg hregAMD64_FAKE3 ( void );
+extern HReg hregAMD64_FAKE4 ( void );
+extern HReg hregAMD64_FAKE5 ( void );
+
+extern HReg hregAMD64_XMM0 ( void );
+extern HReg hregAMD64_XMM1 ( void );
+extern HReg hregAMD64_XMM2 ( void );
+extern HReg hregAMD64_XMM3 ( void );
+extern HReg hregAMD64_XMM4 ( void );
+extern HReg hregAMD64_XMM5 ( void );
+extern HReg hregAMD64_XMM6 ( void );
+extern HReg hregAMD64_XMM7 ( void );
+extern HReg hregAMD64_XMM8 ( void );
+extern HReg hregAMD64_XMM9 ( void );
+extern HReg hregAMD64_XMM10 ( void );
+extern HReg hregAMD64_XMM11 ( void );
+extern HReg hregAMD64_XMM12 ( void );
+extern HReg hregAMD64_XMM13 ( void );
+extern HReg hregAMD64_XMM14 ( void );
+extern HReg hregAMD64_XMM15 ( void );
+
+
+/* --------- Condition codes, AMD encoding. --------- */
+
+typedef
+ enum {
+ Acc_O = 0, /* overflow */
+ Acc_NO = 1, /* no overflow */
+
+ Acc_B = 2, /* below */
+ Acc_NB = 3, /* not below */
+
+ Acc_Z = 4, /* zero */
+ Acc_NZ = 5, /* not zero */
+
+ Acc_BE = 6, /* below or equal */
+ Acc_NBE = 7, /* not below or equal */
+
+ Acc_S = 8, /* negative */
+ Acc_NS = 9, /* not negative */
+
+ Acc_P = 10, /* parity even */
+ Acc_NP = 11, /* not parity even */
+
+ Acc_L = 12, /* jump less */
+ Acc_NL = 13, /* not less */
+
+ Acc_LE = 14, /* less or equal */
+ Acc_NLE = 15, /* not less or equal */
+
+ Acc_ALWAYS = 16 /* the usual hack */
+ }
+ AMD64CondCode;
+
+extern HChar* showAMD64CondCode ( AMD64CondCode );
+
+
+/* --------- Memory address expressions (amodes). --------- */
+
+typedef
+ enum {
+ Aam_IR, /* Immediate + Reg */
+ Aam_IRRS /* Immediate + Reg1 + (Reg2 << Shift) */
+ }
+ AMD64AModeTag;
+
+typedef
+ struct {
+ AMD64AModeTag tag;
+ union {
+ struct {
+ UInt imm;
+ HReg reg;
+ } IR;
+ struct {
+ UInt imm;
+ HReg base;
+ HReg index;
+ Int shift; /* 0, 1, 2 or 3 only */
+ } IRRS;
+ } Aam;
+ }
+ AMD64AMode;
+
+extern AMD64AMode* AMD64AMode_IR ( UInt, HReg );
+extern AMD64AMode* AMD64AMode_IRRS ( UInt, HReg, HReg, Int );
+
+extern AMD64AMode* dopyAMD64AMode ( AMD64AMode* );
+
+extern void ppAMD64AMode ( AMD64AMode* );
+
+
+/* --------- Operand, which can be reg, immediate or memory. --------- */
+
+typedef
+ enum {
+ Armi_Imm,
+ Armi_Reg,
+ Armi_Mem
+ }
+ AMD64RMITag;
+
+typedef
+ struct {
+ AMD64RMITag tag;
+ union {
+ struct {
+ UInt imm32;
+ } Imm;
+ struct {
+ HReg reg;
+ } Reg;
+ struct {
+ AMD64AMode* am;
+ } Mem;
+ }
+ Armi;
+ }
+ AMD64RMI;
+
+extern AMD64RMI* AMD64RMI_Imm ( UInt );
+extern AMD64RMI* AMD64RMI_Reg ( HReg );
+extern AMD64RMI* AMD64RMI_Mem ( AMD64AMode* );
+
+extern void ppAMD64RMI ( AMD64RMI* );
+
+
+/* --------- Operand, which can be reg or immediate only. --------- */
+
+typedef
+ enum {
+ Ari_Imm,
+ Ari_Reg
+ }
+ AMD64RITag;
+
+typedef
+ struct {
+ AMD64RITag tag;
+ union {
+ struct {
+ UInt imm32;
+ } Imm;
+ struct {
+ HReg reg;
+ } Reg;
+ }
+ Ari;
+ }
+ AMD64RI;
+
+extern AMD64RI* AMD64RI_Imm ( UInt );
+extern AMD64RI* AMD64RI_Reg ( HReg );
+
+extern void ppAMD64RI ( AMD64RI* );
+
+
+/* --------- Operand, which can be reg or memory only. --------- */
+
+typedef
+ enum {
+ Arm_Reg,
+ Arm_Mem
+ }
+ AMD64RMTag;
+
+typedef
+ struct {
+ AMD64RMTag tag;
+ union {
+ struct {
+ HReg reg;
+ } Reg;
+ struct {
+ AMD64AMode* am;
+ } Mem;
+ }
+ Arm;
+ }
+ AMD64RM;
+
+extern AMD64RM* AMD64RM_Reg ( HReg );
+extern AMD64RM* AMD64RM_Mem ( AMD64AMode* );
+
+extern void ppAMD64RM ( AMD64RM* );
+
+
//.. /* --------- Instructions. --------- */
//..
//.. /* --------- */
//.. X86SseOp;
//..
//.. extern HChar* showX86SseOp ( X86SseOp );
-//..
-//..
-//.. /* --------- */
-//.. typedef
-//.. enum {
-//.. Xin_Alu32R, /* 32-bit mov/arith/logical, dst=REG */
-//.. Xin_Alu32M, /* 32-bit mov/arith/logical, dst=MEM */
+
+
+/* --------- */
+typedef
+ enum {
+ Ain_Alu64R, /* 64-bit mov/arith/logical, dst=REG */
+ Ain_Alu64M, /* 64-bit mov/arith/logical, dst=MEM */
//.. Xin_Sh32, /* 32-bit shift/rotate, dst=REG or MEM */
//.. Xin_Test32, /* 32-bit test (AND, set flags, discard result) */
//.. Xin_Unary32, /* 32-bit not and neg */
//.. Xin_SseReRg, /* SSE binary general reg-reg, Re, Rg */
//.. Xin_SseCMov, /* SSE conditional move */
//.. Xin_SseShuf /* SSE2 shuffle (pshufd) */
-//.. }
-//.. X86InstrTag;
-//..
-//.. /* Destinations are on the RIGHT (second operand) */
-//..
-//.. typedef
-//.. struct {
-//.. X86InstrTag tag;
+ }
+ AMD64InstrTag;
+
+/* Destinations are on the RIGHT (second operand) */
+
+typedef
+ struct {
+ AMD64InstrTag tag;
//.. union {
//.. struct {
//.. X86AluOp op;
//.. } SseShuf;
//..
//.. } Xin;
-//.. }
-//.. X86Instr;
-//..
+ }
+ AMD64Instr;
+
//.. extern X86Instr* X86Instr_Alu32R ( X86AluOp, X86RMI*, HReg );
//.. extern X86Instr* X86Instr_Alu32M ( X86AluOp, X86RI*, X86AMode* );
//.. extern X86Instr* X86Instr_Unary32 ( X86UnaryOp op, X86RM* dst );
//.. extern X86Instr* X86Instr_SseReRg ( X86SseOp, HReg, HReg );
//.. extern X86Instr* X86Instr_SseCMov ( X86CondCode, HReg src, HReg dst );
//.. extern X86Instr* X86Instr_SseShuf ( Int order, HReg src, HReg dst );
-//..
-//..
-//.. extern void ppX86Instr ( X86Instr* );
-//..
-//.. /* Some functions that insulate the register allocator from details
-//.. of the underlying instruction set. */
-//.. 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** );
-//.. extern HInstrArray* iselBB_X86 ( IRBB*, VexSubArch );
+
+
+extern void ppAMD64Instr ( AMD64Instr* );
+
+/* Some functions that insulate the register allocator from details
+ of the underlying instruction set. */
+extern void getRegUsage_AMD64Instr ( HRegUsage*, AMD64Instr* );
+extern void mapRegs_AMD64Instr ( HRegRemap*, AMD64Instr* );
+extern Bool isMove_AMD64Instr ( AMD64Instr*, HReg*, HReg* );
+extern Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* );
+extern AMD64Instr* genSpill_AMD64 ( HReg rreg, Int offset );
+extern AMD64Instr* genReload_AMD64 ( HReg rreg, Int offset );
+extern void getAllocableRegs_AMD64 ( Int*, HReg** );
+extern HInstrArray* iselBB_AMD64 ( IRBB*, VexSubArch );
#endif /* ndef __LIBVEX_HOST_AMD64_HDEFS_H */
#include "libvex.h"
//.. #include "ir/irmatch.h"
-//.. #include "main/vex_util.h"
-//.. #include "main/vex_globals.h"
-//.. #include "host-generic/h_generic_regs.h"
+#include "main/vex_util.h"
+#include "main/vex_globals.h"
+#include "host-generic/h_generic_regs.h"
//.. #include "host-generic/h_generic_simd64.h"
-//.. #include "host-x86/hdefs.h"
+#include "host-amd64/hdefs.h"
//..
//..
//.. /*---------------------------------------------------------*/
//.. {
//.. return IRExpr_Binder(binder);
//.. }
-//..
-//..
-//..
-//.. /*---------------------------------------------------------*/
-//.. /*--- ISelEnv ---*/
-//.. /*---------------------------------------------------------*/
-//..
-//.. /* This carries around:
-//..
-//.. - A mapping from IRTemp to IRType, giving the type of any IRTemp we
-//.. might encounter. This is computed before insn selection starts,
-//.. and does not change.
-//..
-//.. - A mapping from IRTemp to HReg. This tells the insn selector
-//.. which virtual register(s) are associated with each IRTemp
-//.. temporary. This is computed before insn selection starts, and
-//.. does not change. We expect this mapping to map precisely the
-//.. same set of IRTemps as the type mapping does.
-//..
-//.. - vregmap holds the primary register for the IRTemp.
-//.. - vregmapHI is only used for 64-bit integer-typed
-//.. IRTemps. It holds the identity of a second
-//.. 32-bit virtual HReg, which holds the high half
-//.. of the value.
-//..
-//.. - The code array, that is, the insns selected so far.
-//..
-//.. - A counter, for generating new virtual registers.
-//..
-//.. - The host subarchitecture we are selecting insns for.
-//.. This is set at the start and does not change.
-//..
-//.. Note, this is all host-independent. */
-//..
-//.. typedef
-//.. struct {
-//.. IRTypeEnv* type_env;
-//..
-//.. HReg* vregmap;
-//.. HReg* vregmapHI;
-//.. Int n_vregmap;
-//..
-//.. HInstrArray* code;
-//..
-//.. Int vreg_ctr;
-//..
-//.. VexSubArch subarch;
-//.. }
-//.. ISelEnv;
-//..
-//..
-//.. static HReg lookupIRTemp ( ISelEnv* env, IRTemp tmp )
-//.. {
-//.. vassert(tmp >= 0);
-//.. vassert(tmp < env->n_vregmap);
-//.. return env->vregmap[tmp];
-//.. }
-//..
+
+
+
+/*---------------------------------------------------------*/
+/*--- ISelEnv ---*/
+/*---------------------------------------------------------*/
+
+/* This carries around:
+
+ - A mapping from IRTemp to IRType, giving the type of any IRTemp we
+ might encounter. This is computed before insn selection starts,
+ and does not change.
+
+ - A mapping from IRTemp to HReg. This tells the insn selector
+ which virtual register is associated with each IRTemp
+ temporary. This is computed before insn selection starts, and
+ does not change. We expect this mapping to map precisely the
+ same set of IRTemps as the type mapping does.
+
+ - The code array, that is, the insns selected so far.
+
+ - A counter, for generating new virtual registers.
+
+ - The host subarchitecture we are selecting insns for.
+ This is set at the start and does not change.
+
+ Note, this is all host-independent. (JRS 20050201: well, kinda
+ ... not completely. Compare with ISelEnv for X86.)
+*/
+
+typedef
+ struct {
+ IRTypeEnv* type_env;
+
+ HReg* vregmap;
+ Int n_vregmap;
+
+ HInstrArray* code;
+
+ Int vreg_ctr;
+
+ VexSubArch subarch;
+ }
+ ISelEnv;
+
+
+static HReg lookupIRTemp ( ISelEnv* env, IRTemp tmp )
+{
+ vassert(tmp >= 0);
+ vassert(tmp < env->n_vregmap);
+ return env->vregmap[tmp];
+}
+
//.. static void lookupIRTemp64 ( HReg* vrHI, HReg* vrLO, ISelEnv* env, IRTemp tmp )
//.. {
//.. vassert(tmp >= 0);
//.. # undef REQUIRE_SSE1
//.. # undef REQUIRE_SSE2
//.. }
-//..
-//..
-//.. /*---------------------------------------------------------*/
-//.. /*--- ISEL: Statements ---*/
-//.. /*---------------------------------------------------------*/
-//..
-//.. static void iselStmt ( ISelEnv* env, IRStmt* stmt )
-//.. {
-//.. if (vex_traceflags & VEX_TRACE_VCODE) {
-//.. vex_printf("\n-- ");
-//.. ppIRStmt(stmt);
-//.. vex_printf("\n");
-//.. }
-//..
-//.. switch (stmt->tag) {
-//..
+
+
+/*---------------------------------------------------------*/
+/*--- ISEL: Statements ---*/
+/*---------------------------------------------------------*/
+
+static void iselStmt ( ISelEnv* env, IRStmt* stmt )
+{
+ if (vex_traceflags & VEX_TRACE_VCODE) {
+ vex_printf("\n-- ");
+ ppIRStmt(stmt);
+ vex_printf("\n");
+ }
+
+ switch (stmt->tag) {
+
//.. /* --------- STORE --------- */
//.. case Ist_STle: {
//.. X86AMode* am;
//.. addInstr(env, X86Instr_Goto(stmt->Ist.Exit.jk, cc, dst));
//.. return;
//.. }
-//..
-//.. default: break;
-//.. }
-//.. ppIRStmt(stmt);
-//.. vpanic("iselStmt");
-//.. }
-//..
-//..
-//.. /*---------------------------------------------------------*/
-//.. /*--- ISEL: Basic block terminators (Nexts) ---*/
-//.. /*---------------------------------------------------------*/
-//..
-//.. static void iselNext ( ISelEnv* env, IRExpr* next, IRJumpKind jk )
-//.. {
+
+ default: break;
+ }
+ ppIRStmt(stmt);
+ vpanic("iselStmt(amd64)");
+}
+
+
+/*---------------------------------------------------------*/
+/*--- ISEL: Basic block terminators (Nexts) ---*/
+/*---------------------------------------------------------*/
+
+static void iselNext ( ISelEnv* env, IRExpr* next, IRJumpKind jk )
+{vassert(0);
//.. X86RI* ri;
//.. if (vex_traceflags & VEX_TRACE_VCODE) {
//.. vex_printf("\n-- goto {");
//.. }
//.. ri = iselIntExpr_RI(env, next);
//.. addInstr(env, X86Instr_Goto(jk, Xcc_ALWAYS,ri));
-//.. }
-//..
-//..
-//.. /*---------------------------------------------------------*/
-//.. /*--- Insn selector top-level ---*/
-//.. /*---------------------------------------------------------*/
-//..
-//.. /* Translate an entire BB to x86 code. */
-//..
-//.. HInstrArray* iselBB_X86 ( IRBB* bb, VexSubArch subarch_host )
-//.. {
-//.. Int i, j;
-//.. HReg hreg, hregHI;
-//..
-//.. /* sanity ... */
-//.. vassert(subarch_host == VexSubArchX86_sse0
-//.. || subarch_host == VexSubArchX86_sse1
-//.. || subarch_host == VexSubArchX86_sse2);
-//..
-//.. /* Make up an initial environment to use. */
-//.. ISelEnv* env = LibVEX_Alloc(sizeof(ISelEnv));
-//.. env->vreg_ctr = 0;
-//..
-//.. /* Set up output code array. */
-//.. env->code = newHInstrArray();
-//..
-//.. /* Copy BB's type env. */
-//.. env->type_env = bb->tyenv;
-//..
-//.. /* Make up an IRTemp -> virtual HReg mapping. This doesn't
-//.. change as we go along. */
-//.. env->n_vregmap = bb->tyenv->types_used;
-//.. env->vregmap = LibVEX_Alloc(env->n_vregmap * sizeof(HReg));
-//.. env->vregmapHI = LibVEX_Alloc(env->n_vregmap * sizeof(HReg));
-//..
-//.. /* and finally ... */
-//.. env->subarch = subarch_host;
-//..
-//.. /* For each IR temporary, allocate a suitably-kinded virtual
-//.. register. */
-//.. j = 0;
-//.. for (i = 0; i < env->n_vregmap; i++) {
-//.. hregHI = hreg = INVALID_HREG;
-//.. switch (bb->tyenv->types[i]) {
-//.. case Ity_I1:
-//.. case Ity_I8:
-//.. case Ity_I16:
-//.. case Ity_I32: hreg = mkHReg(j++, HRcInt32, True); break;
-//.. case Ity_I64: hreg = mkHReg(j++, HRcInt32, True);
-//.. hregHI = mkHReg(j++, HRcInt32, True); break;
-//.. case Ity_F32:
-//.. case Ity_F64: hreg = mkHReg(j++, HRcFlt64, True); break;
-//.. case Ity_V128: hreg = mkHReg(j++, HRcVec128, True); break;
-//.. default: ppIRType(bb->tyenv->types[i]);
-//.. vpanic("iselBB: IRTemp type");
-//.. }
-//.. env->vregmap[i] = hreg;
-//.. env->vregmapHI[i] = hregHI;
-//.. }
-//.. env->vreg_ctr = j;
-//..
-//.. /* Ok, finally we can iterate over the statements. */
-//.. for (i = 0; i < bb->stmts_used; i++)
-//.. if (bb->stmts[i])
-//.. iselStmt(env,bb->stmts[i]);
-//..
-//.. iselNext(env,bb->next,bb->jumpkind);
-//..
-//.. /* record the number of vregs we used. */
-//.. env->code->n_vregs = env->vreg_ctr;
-//.. return env->code;
-//.. }
+}
+
+
+/*---------------------------------------------------------*/
+/*--- Insn selector top-level ---*/
+/*---------------------------------------------------------*/
+
+/* Translate an entire BB to amd64 code. */
+
+HInstrArray* iselBB_AMD64 ( IRBB* bb, VexSubArch subarch_host )
+{
+ Int i, j;
+ HReg hreg;
+
+ /* sanity ... */
+ vassert(subarch_host == VexSubArch_NONE);
+
+ /* Make up an initial environment to use. */
+ ISelEnv* env = LibVEX_Alloc(sizeof(ISelEnv));
+ env->vreg_ctr = 0;
+
+ /* Set up output code array. */
+ env->code = newHInstrArray();
+
+ /* Copy BB's type env. */
+ env->type_env = bb->tyenv;
+
+ /* Make up an IRTemp -> virtual HReg mapping. This doesn't
+ change as we go along. */
+ env->n_vregmap = bb->tyenv->types_used;
+ env->vregmap = LibVEX_Alloc(env->n_vregmap * sizeof(HReg));
+
+ /* and finally ... */
+ env->subarch = subarch_host;
+
+ /* For each IR temporary, allocate a suitably-kinded virtual
+ register. */
+ j = 0;
+ for (i = 0; i < env->n_vregmap; i++) {
+ hreg = INVALID_HREG;
+ switch (bb->tyenv->types[i]) {
+ case Ity_I1:
+ case Ity_I8:
+ case Ity_I16:
+ case Ity_I32:
+ case Ity_I64: hreg = mkHReg(j++, HRcInt64, True); break;
+ case Ity_F32:
+ case Ity_F64: hreg = mkHReg(j++, HRcFlt64, True); break;
+ case Ity_V128: hreg = mkHReg(j++, HRcVec128, True); break;
+ default: ppIRType(bb->tyenv->types[i]);
+ vpanic("iselBB(amd64): IRTemp type");
+ }
+ env->vregmap[i] = hreg;
+ }
+ env->vreg_ctr = j;
+
+ /* Ok, finally we can iterate over the statements. */
+ for (i = 0; i < bb->stmts_used; i++)
+ if (bb->stmts[i])
+ iselStmt(env,bb->stmts[i]);
+
+ iselNext(env,bb->next,bb->jumpkind);
+
+ /* record the number of vregs we used. */
+ env->code->n_vregs = env->vreg_ctr;
+ return env->code;
+}
/*---------------------------------------------------------------*/
#include "ir/iropt.h"
#include "host-x86/hdefs.h"
+#include "host-amd64/hdefs.h"
#include "guest-x86/gdefs.h"
#include "guest-amd64/gdefs.h"
|| subarch_host == VexSubArchX86_sse2);
break;
+ case VexArchAMD64:
+ getAllocableRegs_AMD64 ( &n_available_real_regs,
+ &available_real_regs );
+ isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
+ getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_AMD64Instr;
+ mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_AMD64Instr;
+ genSpill = (HInstr*(*)(HReg,Int)) genSpill_AMD64;
+ genReload = (HInstr*(*)(HReg,Int)) genReload_AMD64;
+ ppInstr = (void(*)(HInstr*)) ppAMD64Instr;
+ ppReg = (void(*)(HReg)) ppHRegAMD64;
+ iselBB = iselBB_AMD64;
+ emit = (Int(*)(UChar*,Int,HInstr*)) emit_AMD64Instr;
+ host_is_bigendian = False;
+ host_word_type = Ity_I64;
+ vassert(subarch_host == VexSubArch_NONE);
+ break;
+
default:
vpanic("LibVEX_Translate: unsupported target insn set");
}
vex_printf("\n");
}
+ if (0) { *host_bytes_used = 0; return VexTransOK; }
+
if (vex_traceflags & VEX_TRACE_VCODE)
vex_printf("\n------------------------"
" Instruction selection "