]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Get the AMD64 back-end show on the road.
authorJulian Seward <jseward@acm.org>
Tue, 1 Feb 2005 20:30:00 +0000 (20:30 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 1 Feb 2005 20:30:00 +0000 (20:30 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@810

VEX/priv/host-amd64/hdefs.c
VEX/priv/host-amd64/hdefs.h
VEX/priv/host-amd64/isel.c
VEX/priv/main/vex_main.c

index c261e8144491fdfb62ff6a5500a7815ed6bc5208..e47f34abeb13e249daaea7db954caa8ee0a7f19c 100644 (file)
 #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" };
@@ -74,8 +74,8 @@
 //..       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 ---*/
index 4cfb4ae78d7e7fca804d4eff43a229b79beb0e6f..53cbcb53811da1ca6e2230617711a3c16b753fc4 100644 (file)
 #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 */
 
index 14c3d95ed0e47a7fd32b8d96d15a250c54093f42..27846991e8620094cb27b0be37cf2da14b7751db 100644 (file)
 #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;
+}
 
 
 /*---------------------------------------------------------------*/
index 3c99420f68e86b8540f5728aff78de0b6cdb4d5b..01567a0e75a490f14f21d01df23b4e3f8070f757 100644 (file)
@@ -46,6 +46,7 @@
 #include "ir/iropt.h"
 
 #include "host-x86/hdefs.h"
+#include "host-amd64/hdefs.h"
 
 #include "guest-x86/gdefs.h"
 #include "guest-amd64/gdefs.h"
@@ -265,6 +266,23 @@ VexTranslateResult LibVEX_Translate (
                  || 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");
    }
@@ -433,6 +451,8 @@ VexTranslateResult LibVEX_Translate (
       vex_printf("\n");
    }
 
+   if (0) { *host_bytes_used = 0; return VexTransOK; }
+
    if (vex_traceflags & VEX_TRACE_VCODE)
       vex_printf("\n------------------------" 
                    " Instruction selection "