Fix many instruction selection cases, including function calls.
git-svn-id: svn://svn.valgrind.org/vex/trunk@833 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/host-amd64/hdefs.c b/priv/host-amd64/hdefs.c
index b9a7a8f..e263bbc 100644
--- a/priv/host-amd64/hdefs.c
+++ b/priv/host-amd64/hdefs.c
@@ -408,12 +408,12 @@
op->Arm.Reg.reg = reg;
return op;
}
-//.. AMD64RM* AMD64RM_Mem ( AMD64AMode* am ) {
-//.. AMD64RM* op = LibVEX_Alloc(sizeof(AMD64RM));
-//.. op->tag = Xrm_Mem;
-//.. op->Xrm.Mem.am = am;
-//.. return op;
-//.. }
+AMD64RM* AMD64RM_Mem ( AMD64AMode* am ) {
+ AMD64RM* op = LibVEX_Alloc(sizeof(AMD64RM));
+ op->tag = Arm_Mem;
+ op->Arm.Mem.am = am;
+ return op;
+}
void ppAMD64RM ( AMD64RM* op ) {
switch (op->tag) {
@@ -630,13 +630,13 @@
i->Ain.Sh64.dst = dst;
return i;
}
-//.. AMD64Instr* AMD64Instr_Test32 ( AMD64RI* src, AMD64RM* dst ) {
-//.. AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
-//.. i->tag = Xin_Test32;
-//.. i->Xin.Test32.src = src;
-//.. i->Xin.Test32.dst = dst;
-//.. return i;
-//.. }
+AMD64Instr* AMD64Instr_Test64 ( AMD64RI* src, AMD64RM* dst ) {
+ AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
+ i->tag = Ain_Test64;
+ i->Ain.Test64.src = src;
+ i->Ain.Test64.dst = dst;
+ return i;
+}
//.. AMD64Instr* AMD64Instr_Unary32 ( AMD64UnaryOp op, AMD64RM* dst ) {
//.. AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
//.. i->tag = Xin_Unary32;
@@ -676,15 +676,15 @@
//.. i->Xin.Push.src = src;
//.. return i;
//.. }
-//.. AMD64Instr* AMD64Instr_Call ( AMD64CondCode cond, Addr32 target, Int regparms ) {
-//.. AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
-//.. i->tag = Xin_Call;
-//.. i->Xin.Call.cond = cond;
-//.. i->Xin.Call.target = target;
-//.. i->Xin.Call.regparms = regparms;
-//.. vassert(regparms >= 0 && regparms <= 3);
-//.. return i;
-//.. }
+AMD64Instr* AMD64Instr_Call ( AMD64CondCode cond, Addr64 target, Int regparms ) {
+ AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
+ i->tag = Ain_Call;
+ i->Ain.Call.cond = cond;
+ i->Ain.Call.target = target;
+ i->Ain.Call.regparms = regparms;
+ vassert(regparms >= 0 && regparms <= 6);
+ return i;
+}
AMD64Instr* AMD64Instr_Goto ( IRJumpKind jk, AMD64CondCode cond, AMD64RI* dst ) {
AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
i->tag = Ain_Goto;
@@ -693,15 +693,15 @@
i->Ain.Goto.jk = jk;
return i;
}
-//.. AMD64Instr* AMD64Instr_CMov32 ( AMD64CondCode cond, AMD64RM* src, HReg dst ) {
-//.. AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
-//.. i->tag = Xin_CMov32;
-//.. i->Xin.CMov32.cond = cond;
-//.. i->Xin.CMov32.src = src;
-//.. i->Xin.CMov32.dst = dst;
-//.. vassert(cond != Xcc_ALWAYS);
-//.. return i;
-//.. }
+AMD64Instr* AMD64Instr_CMov64 ( AMD64CondCode cond, AMD64RM* src, HReg dst ) {
+ AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
+ i->tag = Ain_CMov64;
+ i->Ain.CMov64.cond = cond;
+ i->Ain.CMov64.src = src;
+ i->Ain.CMov64.dst = dst;
+ vassert(cond != Acc_ALWAYS);
+ return i;
+}
AMD64Instr* AMD64Instr_MovZLQ ( HReg src, HReg dst ) {
AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
i->tag = Ain_MovZLQ;
@@ -942,12 +942,12 @@
vex_printf("$%d,", i->Ain.Sh64.src);
ppAMD64RM(i->Ain.Sh64.dst);
return;
-//.. case Xin_Test32:
-//.. vex_printf("testl ");
-//.. ppAMD64RI(i->Xin.Test32.src);
-//.. vex_printf(",");
-//.. ppAMD64RM(i->Xin.Test32.dst);
-//.. return;
+ case Ain_Test64:
+ vex_printf("testq ");
+ ppAMD64RI(i->Ain.Test64.src);
+ vex_printf(",");
+ ppAMD64RM(i->Ain.Test64.dst);
+ return;
//.. case Xin_Unary32:
//.. vex_printf("%sl ", showAMD64UnaryOp(i->Xin.Unary32.op));
//.. ppAMD64RM(i->Xin.Unary32.dst);
@@ -978,13 +978,13 @@
//.. vex_printf("pushl ");
//.. ppAMD64RMI(i->Xin.Push.src);
//.. return;
-//.. case Xin_Call:
-//.. vex_printf("call%s[%d] ",
-//.. i->Xin.Call.cond==Xcc_ALWAYS
-//.. ? "" : showAMD64CondCode(i->Xin.Call.cond),
-//.. i->Xin.Call.regparms);
-//.. vex_printf("0x%x", i->Xin.Call.target);
-//.. break;
+ case Ain_Call:
+ vex_printf("call%s[%d] ",
+ i->Ain.Call.cond==Acc_ALWAYS
+ ? "" : showAMD64CondCode(i->Ain.Call.cond),
+ i->Ain.Call.regparms );
+ vex_printf("0x%llx", i->Ain.Call.target);
+ break;
case Ain_Goto:
if (i->Ain.Goto.cond != Acc_ALWAYS) {
vex_printf("if (%%rflags.%s) { ",
@@ -1002,12 +1002,12 @@
vex_printf(" }");
}
return;
-//.. case Xin_CMov32:
-//.. vex_printf("cmov%s ", showAMD64CondCode(i->Xin.CMov32.cond));
-//.. ppAMD64RM(i->Xin.CMov32.src);
-//.. vex_printf(",");
-//.. ppHRegAMD64(i->Xin.CMov32.dst);
-//.. return;
+ case Ain_CMov64:
+ vex_printf("cmov%s ", showAMD64CondCode(i->Ain.CMov64.cond));
+ ppAMD64RM(i->Ain.CMov64.src);
+ vex_printf(",");
+ ppHRegAMD64(i->Ain.CMov64.dst);
+ return;
case Ain_MovZLQ:
vex_printf("movzlq ");
ppHRegAMD64(i->Ain.MovZLQ.src);
@@ -1024,12 +1024,13 @@
vex_printf(",");
ppHRegAMD64(i->Ain.LoadEX.dst);
return;
-//.. case Xin_Store:
-//.. vex_printf("mov%c ", i->Xin.Store.sz==1 ? 'b' : 'w');
-//.. ppHRegAMD64(i->Xin.Store.src);
-//.. vex_printf(",");
-//.. ppAMD64AMode(i->Xin.Store.dst);
-//.. return;
+ case Ain_Store:
+ vex_printf("mov%c ", i->Ain.Store.sz==1 ? 'b'
+ : (i->Ain.Store.sz==2 ? 'w' : 'l'));
+ ppHRegAMD64(i->Ain.Store.src);
+ vex_printf(",");
+ ppAMD64AMode(i->Ain.Store.dst);
+ return;
//.. case Xin_Set32:
//.. vex_printf("setl%s ", showAMD64CondCode(i->Xin.Set32.cond));
//.. ppHRegAMD64(i->Xin.Set32.dst);
@@ -1211,10 +1212,10 @@
if (i->Ain.Sh64.src == 0)
addHRegUse(u, HRmRead, hregAMD64_RCX());
return;
-//.. case Xin_Test32:
-//.. addRegUsage_AMD64RI(u, i->Xin.Test32.src);
-//.. addRegUsage_AMD64RM(u, i->Xin.Test32.dst, HRmRead);
-//.. return;
+ case Ain_Test64:
+ addRegUsage_AMD64RI(u, i->Ain.Test64.src);
+ addRegUsage_AMD64RM(u, i->Ain.Test64.dst, HRmRead);
+ return;
//.. case Xin_Unary32:
//.. addRegUsage_AMD64RM(u, i->Xin.Unary32.dst, HRmModify);
//.. return;
@@ -1238,47 +1239,52 @@
//.. addRegUsage_AMD64RMI(u, i->Xin.Push.src);
//.. addHRegUse(u, HRmModify, hregAMD64_ESP());
//.. return;
-//.. case Xin_Call:
-//.. /* This is a bit subtle. */
-//.. /* First off, claim it trashes all the callee-saved regs */
-//.. /* which I believe to be %eax,%ecx,%edx. */
-//.. addHRegUse(u, HRmWrite, hregAMD64_EAX());
-//.. addHRegUse(u, HRmWrite, hregAMD64_ECX());
-//.. addHRegUse(u, HRmWrite, hregAMD64_EDX());
-//.. /* Now we have to state any parameter-carrying registers
-//.. which might be read. This depends on the regparmness. */
-//.. switch (i->Xin.Call.regparms) {
-//.. case 3: addHRegUse(u, HRmRead, hregAMD64_ECX()); /*fallthru*/
-//.. case 2: addHRegUse(u, HRmRead, hregAMD64_EDX()); /*fallthru*/
-//.. case 1: addHRegUse(u, HRmRead, hregAMD64_EAX()); break;
-//.. case 0: break;
-//.. default: vpanic("getRegUsage_AMD64Instr:Call:regparms");
-//.. }
-//.. /* Finally, there is the issue that the insn trashes a
-//.. register because the literal target address has to be
-//.. loaded into a register. Fortunately, for the 0/1/2
-//.. regparm case, we can use EAX, EDX and ECX respectively, so
-//.. this does not cause any further damage. For the 3-regparm
-//.. case, we'll have to choose another register arbitrarily --
-//.. since A, D and C are used for parameters -- and so we might
-//.. as well choose EDI. */
-//.. if (i->Xin.Call.regparms == 3)
-//.. addHRegUse(u, HRmWrite, hregAMD64_EDI());
-//.. /* Upshot of this is that the assembler really must observe
-//.. the here-stated convention of which register to use as an
-//.. address temporary, depending on the regparmness: 0==EAX,
-//.. 1==EDX, 2==ECX, 3==EDI. */
-//.. return;
+ case Ain_Call:
+ /* This is a bit subtle. */
+ /* First off, claim it trashes all the caller-saved regs
+ which fall within the register allocator's jurisdiction.
+ These I believe to be: rax rcx rdx rsi rdi r8 r9 r10 r11
+ */
+ addHRegUse(u, HRmWrite, hregAMD64_RAX());
+ addHRegUse(u, HRmWrite, hregAMD64_RCX());
+ addHRegUse(u, HRmWrite, hregAMD64_RDX());
+ addHRegUse(u, HRmWrite, hregAMD64_RSI());
+ addHRegUse(u, HRmWrite, hregAMD64_RDI());
+ addHRegUse(u, HRmWrite, hregAMD64_R8());
+ addHRegUse(u, HRmWrite, hregAMD64_R9());
+ addHRegUse(u, HRmWrite, hregAMD64_R10());
+ addHRegUse(u, HRmWrite, hregAMD64_R11());
+
+ /* Now we have to state any parameter-carrying registers
+ which might be read. This depends on the regparmness. */
+ switch (i->Ain.Call.regparms) {
+ case 6: addHRegUse(u, HRmRead, hregAMD64_R9()); /*fallthru*/
+ case 5: addHRegUse(u, HRmRead, hregAMD64_R8()); /*fallthru*/
+ case 4: addHRegUse(u, HRmRead, hregAMD64_RCX()); /*fallthru*/
+ case 3: addHRegUse(u, HRmRead, hregAMD64_RDX()); /*fallthru*/
+ case 2: addHRegUse(u, HRmRead, hregAMD64_RSI()); /*fallthru*/
+ case 1: addHRegUse(u, HRmRead, hregAMD64_RDI()); break;
+ case 0: break;
+ default: vpanic("getRegUsage_AMD64Instr:Call:regparms");
+ }
+ /* Finally, there is the issue that the insn trashes a
+ register because the literal target address has to be
+ loaded into a register. Fortunately, r11 is stated in the
+ ABI as a scratch register, and so seems a suitable victim. */
+ addHRegUse(u, HRmWrite, hregAMD64_R11());
+ /* Upshot of this is that the assembler really must use r11,
+ and no other, as a destination temporary. */
+ return;
case Ain_Goto:
addRegUsage_AMD64RI(u, i->Ain.Goto.dst);
addHRegUse(u, HRmWrite, hregAMD64_RAX());
if (i->Ain.Goto.jk != Ijk_Boring)
addHRegUse(u, HRmWrite, hregAMD64_RBP());
return;
-//.. case Xin_CMov32:
-//.. addRegUsage_AMD64RM(u, i->Xin.CMov32.src, HRmRead);
-//.. addHRegUse(u, HRmModify, i->Xin.CMov32.dst);
-//.. return;
+ case Ain_CMov64:
+ addRegUsage_AMD64RM(u, i->Ain.CMov64.src, HRmRead);
+ addHRegUse(u, HRmModify, i->Ain.CMov64.dst);
+ return;
case Ain_MovZLQ:
addHRegUse(u, HRmRead, i->Ain.MovZLQ.src);
addHRegUse(u, HRmWrite, i->Ain.MovZLQ.dst);
@@ -1287,10 +1293,10 @@
addRegUsage_AMD64AMode(u, i->Ain.LoadEX.src);
addHRegUse(u, HRmWrite, i->Ain.LoadEX.dst);
return;
-//.. case Xin_Store:
-//.. addHRegUse(u, HRmRead, i->Xin.Store.src);
-//.. addRegUsage_AMD64AMode(u, i->Xin.Store.dst);
-//.. return;
+ case Ain_Store:
+ addHRegUse(u, HRmRead, i->Ain.Store.src);
+ addRegUsage_AMD64AMode(u, i->Ain.Store.dst);
+ return;
//.. case Xin_Set32:
//.. addHRegUse(u, HRmWrite, i->Xin.Set32.dst);
//.. return;
@@ -1434,10 +1440,10 @@
case Ain_Sh64:
mapRegs_AMD64RM(m, i->Ain.Sh64.dst);
return;
-//.. case Xin_Test32:
-//.. mapRegs_AMD64RI(m, i->Xin.Test32.src);
-//.. mapRegs_AMD64RM(m, i->Xin.Test32.dst);
-//.. return;
+ case Ain_Test64:
+ mapRegs_AMD64RI(m, i->Ain.Test64.src);
+ mapRegs_AMD64RM(m, i->Ain.Test64.dst);
+ return;
//.. case Xin_Unary32:
//.. mapRegs_AMD64RM(m, i->Xin.Unary32.dst);
//.. return;
@@ -1454,15 +1460,15 @@
//.. case Xin_Push:
//.. mapRegs_AMD64RMI(m, i->Xin.Push.src);
//.. return;
-//.. case Xin_Call:
-//.. return;
+ case Ain_Call:
+ return;
case Ain_Goto:
mapRegs_AMD64RI(m, i->Ain.Goto.dst);
return;
-//.. case Xin_CMov32:
-//.. mapRegs_AMD64RM(m, i->Xin.CMov32.src);
-//.. mapReg(m, &i->Xin.CMov32.dst);
-//.. return;
+ case Ain_CMov64:
+ mapRegs_AMD64RM(m, i->Ain.CMov64.src);
+ mapReg(m, &i->Ain.CMov64.dst);
+ return;
case Ain_MovZLQ:
mapReg(m, &i->Ain.MovZLQ.src);
mapReg(m, &i->Ain.MovZLQ.dst);
@@ -1471,10 +1477,10 @@
mapRegs_AMD64AMode(m, i->Ain.LoadEX.src);
mapReg(m, &i->Ain.LoadEX.dst);
return;
-//.. case Xin_Store:
-//.. mapReg(m, &i->Xin.Store.src);
-//.. mapRegs_AMD64AMode(m, i->Xin.Store.dst);
-//.. return;
+ case Ain_Store:
+ mapReg(m, &i->Ain.Store.src);
+ mapRegs_AMD64AMode(m, i->Ain.Store.dst);
+ return;
//.. case Xin_Set32:
//.. mapReg(m, &i->Xin.Set32.dst);
//.. return;