From: Julian Seward Date: Wed, 23 Feb 2005 13:31:25 +0000 (+0000) Subject: Cleaning up the x86 back end: get rid of instruction variants which X-Git-Tag: svn/VALGRIND_3_0_1^2~381 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc97aab5f58b134615e57cf9d1af5a0bbf258624;p=thirdparty%2Fvalgrind.git Cleaning up the x86 back end: get rid of instruction variants which the instruction selector will never generate. I guess this demonstrates that the majority of operations are sufficiently rare that it is not worth going to much effort to generate good code for them. git-svn-id: svn://svn.valgrind.org/vex/trunk@953 --- diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index 0fd7454cfa..b608fba440 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -430,14 +430,6 @@ static void mapRegs_X86RM ( HRegRemap* m, X86RM* op ) /* --------- Instructions. --------- */ -HChar* showX86ScalarSz ( X86ScalarSz sz ) { - switch (sz) { - case Xss_16: return "w"; - case Xss_32: return "l"; - default: vpanic("showX86ScalarSz"); - } -} - HChar* showX86UnaryOp ( X86UnaryOp op ) { switch (op) { case Xun_NOT: return "not"; @@ -587,7 +579,7 @@ X86Instr* X86Instr_Alu32M ( X86AluOp op, X86RI* src, X86AMode* dst ) { vassert(op != Xalu_MUL); return i; } -X86Instr* X86Instr_Sh32 ( X86ShiftOp op, UInt src, X86RM* dst ) { +X86Instr* X86Instr_Sh32 ( X86ShiftOp op, UInt src, HReg dst ) { X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); i->tag = Xin_Sh32; i->Xin.Sh32.op = op; @@ -595,34 +587,32 @@ X86Instr* X86Instr_Sh32 ( X86ShiftOp op, UInt src, X86RM* dst ) { i->Xin.Sh32.dst = dst; return i; } -X86Instr* X86Instr_Test32 ( X86RI* src, X86RM* dst ) { - X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); - i->tag = Xin_Test32; - i->Xin.Test32.src = src; - i->Xin.Test32.dst = dst; +X86Instr* X86Instr_Test32 ( UInt imm32, HReg dst ) { + X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); + i->tag = Xin_Test32; + i->Xin.Test32.imm32 = imm32; + i->Xin.Test32.dst = dst; return i; } -X86Instr* X86Instr_Unary32 ( X86UnaryOp op, X86RM* dst ) { +X86Instr* X86Instr_Unary32 ( X86UnaryOp op, HReg dst ) { X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); i->tag = Xin_Unary32; i->Xin.Unary32.op = op; i->Xin.Unary32.dst = dst; return i; } -X86Instr* X86Instr_MulL ( Bool syned, X86ScalarSz ssz , X86RM* src ) { +X86Instr* X86Instr_MulL ( Bool syned, X86RM* src ) { X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); i->tag = Xin_MulL; i->Xin.MulL.syned = syned; - i->Xin.MulL.ssz = ssz; i->Xin.MulL.src = src; return i; } -X86Instr* X86Instr_Div ( Bool syned, X86ScalarSz ssz, X86RM* src ) { - X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); - i->tag = Xin_Div; - i->Xin.Div.syned = syned; - i->Xin.Div.ssz = ssz; - i->Xin.Div.src = src; +X86Instr* X86Instr_Div ( Bool syned, X86RM* src ) { + X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); + i->tag = Xin_Div; + i->Xin.Div.syned = syned; + i->Xin.Div.src = src; return i; } X86Instr* X86Instr_Sh3232 ( X86ShiftOp op, UInt amt, HReg src, HReg dst ) { @@ -767,11 +757,10 @@ X86Instr* X86Instr_FpCMov ( X86CondCode cond, HReg src, HReg dst ) { vassert(cond != Xcc_ALWAYS); return i; } -X86Instr* X86Instr_FpLdStCW ( Bool isLoad, X86AMode* addr ) { - X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); - i->tag = Xin_FpLdStCW; - i->Xin.FpLdStCW.isLoad = isLoad; - i->Xin.FpLdStCW.addr = addr; +X86Instr* X86Instr_FpLdCW ( X86AMode* addr ) { + X86Instr* i = LibVEX_Alloc(sizeof(X86Instr)); + i->tag = Xin_FpLdCW; + i->Xin.FpLdCW.addr = addr; return i; } X86Instr* X86Instr_FpStSW_AX ( void ) { @@ -897,28 +886,22 @@ void ppX86Instr ( X86Instr* i ) { vex_printf("%%cl,"); else vex_printf("$%d,", i->Xin.Sh32.src); - ppX86RM(i->Xin.Sh32.dst); + ppHRegX86(i->Xin.Sh32.dst); return; case Xin_Test32: - vex_printf("testl "); - ppX86RI(i->Xin.Test32.src); - vex_printf(","); - ppX86RM(i->Xin.Test32.dst); + vex_printf("testl $%d,", i->Xin.Test32.imm32); + ppHRegX86(i->Xin.Test32.dst); return; case Xin_Unary32: vex_printf("%sl ", showX86UnaryOp(i->Xin.Unary32.op)); - ppX86RM(i->Xin.Unary32.dst); + ppHRegX86(i->Xin.Unary32.dst); return; case Xin_MulL: - vex_printf("%cmul%s ", - i->Xin.MulL.syned ? 's' : 'u', - showX86ScalarSz(i->Xin.MulL.ssz)); + vex_printf("%cmull ", i->Xin.MulL.syned ? 's' : 'u'); ppX86RM(i->Xin.MulL.src); return; case Xin_Div: - vex_printf("%cdiv%s ", - i->Xin.Div.syned ? 's' : 'u', - showX86ScalarSz(i->Xin.Div.ssz)); + vex_printf("%cdivl ", i->Xin.Div.syned ? 's' : 'u'); ppX86RM(i->Xin.Div.src); return; case Xin_Sh3232: @@ -1047,9 +1030,9 @@ void ppX86Instr ( X86Instr* i ) { vex_printf(","); ppHRegX86(i->Xin.FpCMov.dst); return; - case Xin_FpLdStCW: - vex_printf(i->Xin.FpLdStCW.isLoad ? "fldcw " : "fstcw "); - ppX86AMode(i->Xin.FpLdStCW.addr); + case Xin_FpLdCW: + vex_printf("fldcw "); + ppX86AMode(i->Xin.FpLdCW.addr); return; case Xin_FpStSW_AX: vex_printf("fstsw %%ax"); @@ -1142,11 +1125,11 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) case Xin_Alu32R: addRegUsage_X86RMI(u, i->Xin.Alu32R.src); if (i->Xin.Alu32R.op == Xalu_MOV) { - addHRegUse(u, HRmWrite, i->Xin.Alu32R.dst); + addHRegUse(u, HRmWrite, i->Xin.Alu32R.dst); return; } if (i->Xin.Alu32R.op == Xalu_CMP) { - addHRegUse(u, HRmRead, i->Xin.Alu32R.dst); + addHRegUse(u, HRmRead, i->Xin.Alu32R.dst); return; } addHRegUse(u, HRmModify, i->Xin.Alu32R.dst); @@ -1156,16 +1139,15 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) addRegUsage_X86AMode(u, i->Xin.Alu32M.dst); return; case Xin_Sh32: - addRegUsage_X86RM(u, i->Xin.Sh32.dst, HRmModify); + addHRegUse(u, HRmModify, i->Xin.Sh32.dst); if (i->Xin.Sh32.src == 0) addHRegUse(u, HRmRead, hregX86_ECX()); return; case Xin_Test32: - addRegUsage_X86RI(u, i->Xin.Test32.src); - addRegUsage_X86RM(u, i->Xin.Test32.dst, HRmRead); + addHRegUse(u, HRmRead, i->Xin.Test32.dst); return; case Xin_Unary32: - addRegUsage_X86RM(u, i->Xin.Unary32.dst, HRmModify); + addHRegUse(u, HRmModify, i->Xin.Unary32.dst); return; case Xin_MulL: addRegUsage_X86RM(u, i->Xin.MulL.src, HRmRead); @@ -1273,8 +1255,8 @@ void getRegUsage_X86Instr (HRegUsage* u, X86Instr* i) addHRegUse(u, HRmRead, i->Xin.FpCMov.src); addHRegUse(u, HRmModify, i->Xin.FpCMov.dst); return; - case Xin_FpLdStCW: - addRegUsage_X86AMode(u, i->Xin.FpLdStCW.addr); + case Xin_FpLdCW: + addRegUsage_X86AMode(u, i->Xin.FpLdCW.addr); return; case Xin_FpStSW_AX: addHRegUse(u, HRmWrite, hregX86_EAX()); @@ -1378,14 +1360,13 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i) mapRegs_X86AMode(m, i->Xin.Alu32M.dst); return; case Xin_Sh32: - mapRegs_X86RM(m, i->Xin.Sh32.dst); + mapReg(m, &i->Xin.Sh32.dst); return; case Xin_Test32: - mapRegs_X86RI(m, i->Xin.Test32.src); - mapRegs_X86RM(m, i->Xin.Test32.dst); + mapReg(m, &i->Xin.Test32.dst); return; case Xin_Unary32: - mapRegs_X86RM(m, i->Xin.Unary32.dst); + mapReg(m, &i->Xin.Unary32.dst); return; case Xin_MulL: mapRegs_X86RM(m, i->Xin.MulL.src); @@ -1451,8 +1432,8 @@ void mapRegs_X86Instr (HRegRemap* m, X86Instr* i) mapReg(m, &i->Xin.FpCMov.src); mapReg(m, &i->Xin.FpCMov.dst); return; - case Xin_FpLdStCW: - mapRegs_X86AMode(m, i->Xin.FpLdStCW.addr); + case Xin_FpLdCW: + mapRegs_X86AMode(m, i->Xin.FpLdCW.addr); return; case Xin_FpStSW_AX: return; @@ -2013,95 +1994,65 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) } if (i->Xin.Sh32.src == 0) { *p++ = opc_cl; - switch (i->Xin.Sh32.dst->tag) { - case Xrm_Reg: - p = doAMode_R(p, fake(subopc), - i->Xin.Sh32.dst->Xrm.Reg.reg); - goto done; - default: - goto bad; - } + p = doAMode_R(p, fake(subopc), i->Xin.Sh32.dst); } else { *p++ = opc_imm; - switch (i->Xin.Sh32.dst->tag) { - case Xrm_Reg: - p = doAMode_R(p, fake(subopc), - i->Xin.Sh32.dst->Xrm.Reg.reg); - *p++ = (UChar)(i->Xin.Sh32.src); - goto done; - default: - goto bad; - } + p = doAMode_R(p, fake(subopc), i->Xin.Sh32.dst); + *p++ = (UChar)(i->Xin.Sh32.src); } - break; + goto done; case Xin_Test32: - if (i->Xin.Test32.src->tag == Xri_Imm - && i->Xin.Test32.dst->tag == Xrm_Reg) { - /* testl $imm32, %reg */ - *p++ = 0xF7; - p = doAMode_R(p, fake(0), i->Xin.Test32.dst->Xrm.Reg.reg); - p = emit32(p, i->Xin.Test32.src->Xri.Imm.imm32); - goto done; - } - break; + /* testl $imm32, %reg */ + *p++ = 0xF7; + p = doAMode_R(p, fake(0), i->Xin.Test32.dst); + p = emit32(p, i->Xin.Test32.imm32); + goto done; case Xin_Unary32: if (i->Xin.Unary32.op == Xun_NOT) { *p++ = 0xF7; - if (i->Xin.Unary32.dst->tag == Xrm_Reg) { - p = doAMode_R(p, fake(2), i->Xin.Unary32.dst->Xrm.Reg.reg); - goto done; - } else { - goto bad; - } + p = doAMode_R(p, fake(2), i->Xin.Unary32.dst); + goto done; } if (i->Xin.Unary32.op == Xun_NEG) { *p++ = 0xF7; - if (i->Xin.Unary32.dst->tag == Xrm_Reg) { - p = doAMode_R(p, fake(3), i->Xin.Unary32.dst->Xrm.Reg.reg); - goto done; - } else { - goto bad; - } + p = doAMode_R(p, fake(3), i->Xin.Unary32.dst); + goto done; } break; case Xin_MulL: subopc = i->Xin.MulL.syned ? 5 : 4; - if (i->Xin.MulL.ssz == Xss_32) { - *p++ = 0xF7; - switch (i->Xin.MulL.src->tag) { - case Xrm_Mem: - p = doAMode_M(p, fake(subopc), - i->Xin.MulL.src->Xrm.Mem.am); - goto done; - case Xrm_Reg: - p = doAMode_R(p, fake(subopc), - i->Xin.MulL.src->Xrm.Reg.reg); - goto done; - default: - goto bad; - } + *p++ = 0xF7; + switch (i->Xin.MulL.src->tag) { + case Xrm_Mem: + p = doAMode_M(p, fake(subopc), + i->Xin.MulL.src->Xrm.Mem.am); + goto done; + case Xrm_Reg: + p = doAMode_R(p, fake(subopc), + i->Xin.MulL.src->Xrm.Reg.reg); + goto done; + default: + goto bad; } break; case Xin_Div: subopc = i->Xin.Div.syned ? 7 : 6; - if (i->Xin.Div.ssz == Xss_32) { - *p++ = 0xF7; - switch (i->Xin.Div.src->tag) { - case Xrm_Mem: - p = doAMode_M(p, fake(subopc), - i->Xin.Div.src->Xrm.Mem.am); - goto done; - case Xrm_Reg: - p = doAMode_R(p, fake(subopc), - i->Xin.Div.src->Xrm.Reg.reg); - goto done; - default: - goto bad; - } + *p++ = 0xF7; + switch (i->Xin.Div.src->tag) { + case Xrm_Mem: + p = doAMode_M(p, fake(subopc), + i->Xin.Div.src->Xrm.Mem.am); + goto done; + case Xrm_Reg: + p = doAMode_R(p, fake(subopc), + i->Xin.Div.src->Xrm.Reg.reg); + goto done; + default: + goto bad; } break; @@ -2232,7 +2183,6 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) case Xin_CMov32: vassert(i->Xin.CMov32.cond != Xcc_ALWAYS); -#if 0 /* This generates cmov, which is illegal on P54/P55. */ *p++ = 0x0F; *p++ = 0x40 + i->Xin.CMov32.cond; @@ -2244,37 +2194,6 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) p = doAMode_M(p, i->Xin.CMov32.dst, i->Xin.CMov32.src->Xrm.Mem.am); goto done; } -#else - /* P5 friendly version: conditional jump over an unconditional - move. */ - /* jmp fwds if !condition */ - *p++ = 0x70 + (i->Xin.CMov32.cond ^ 1); - *p++ = 0; /* # of bytes in the next bit, which we don't know yet */ - ptmp = p; - - switch (i->Xin.CMov32.src->tag) { - case Xrm_Reg: - /* Big sigh. This is movl E -> G ... */ - *p++ = 0x89; - p = doAMode_R(p, i->Xin.CMov32.src->Xrm.Reg.reg, - i->Xin.CMov32.dst); - - break; - case Xrm_Mem: - /* ... whereas this is movl G -> E. That's why the args - to doAMode_R appear to be the wrong way round in the - Xrm_Reg case. */ - *p++ = 0x8B; - p = doAMode_M(p, i->Xin.CMov32.dst, - i->Xin.CMov32.src->Xrm.Mem.am); - break; - default: - goto bad; - } - /* Fill in the jump offset. */ - *(ptmp-1) = p - ptmp; - goto done; -#endif break; case Xin_LoadEX: @@ -2581,13 +2500,9 @@ Int emit_X86Instr ( UChar* buf, Int nbuf, X86Instr* i ) *(ptmp-1) = p - ptmp; goto done; - case Xin_FpLdStCW: - if (i->Xin.FpLdStCW.isLoad) { - *p++ = 0xD9; - p = doAMode_M(p, fake(5)/*subopcode*/, i->Xin.FpLdStCW.addr); - } else { - vassert(0); - } + case Xin_FpLdCW: + *p++ = 0xD9; + p = doAMode_M(p, fake(5)/*subopcode*/, i->Xin.FpLdCW.addr); goto done; case Xin_FpStSW_AX: diff --git a/VEX/priv/host-x86/hdefs.h b/VEX/priv/host-x86/hdefs.h index 8d7b557c90..64c5140b5f 100644 --- a/VEX/priv/host-x86/hdefs.h +++ b/VEX/priv/host-x86/hdefs.h @@ -238,17 +238,6 @@ extern void ppX86RM ( X86RM* ); /* --------- Instructions. --------- */ -/* --------- */ -typedef - enum { - Xss_16, - Xss_32 - } - X86ScalarSz; - -extern HChar* showX86ScalarSz ( X86ScalarSz ); - - /* --------- */ typedef enum { @@ -350,11 +339,12 @@ typedef enum { Xin_Alu32R, /* 32-bit mov/arith/logical, dst=REG */ Xin_Alu32M, /* 32-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_Sh32, /* 32-bit shift/rotate, dst=REG */ + Xin_Test32, /* 32-bit test of REG against imm32 (AND, set + flags, discard result) */ Xin_Unary32, /* 32-bit not and neg */ - Xin_MulL, /* widening multiply */ - Xin_Div, /* div and mod */ + Xin_MulL, /* 32 x 32 -> 64 multiply */ + Xin_Div, /* 64/32 -> (32,32) div and mod */ Xin_Sh3232, /* shldl or shrdl */ Xin_Push, /* push (32-bit?) value on stack */ Xin_Call, /* call to address in register */ @@ -372,7 +362,7 @@ typedef Xin_FpLdStI, /* FP fake load/store, converting to/from Int */ Xin_Fp64to32, /* FP round IEEE754 double to IEEE754 single */ Xin_FpCMov, /* FP fake floating point conditional move */ - Xin_FpLdStCW, /* fldcw / fstcw */ + Xin_FpLdCW, /* fldcw */ Xin_FpStSW_AX, /* fstsw %ax */ Xin_FpCmp, /* FP compare, generating a C320 value into int reg */ @@ -407,29 +397,27 @@ typedef } Alu32M; struct { X86ShiftOp op; - UInt src; /* shift amount, or 0 means %cl */ - X86RM* dst; + UInt src; /* shift amount, or 0 means %cl */ + HReg dst; } Sh32; struct { - X86RI* src; - X86RM* dst; + UInt imm32; + HReg dst; /* not written, only read */ } Test32; /* Not and Neg */ struct { X86UnaryOp op; - X86RM* dst; + HReg dst; } Unary32; - /* DX:AX = AX *s/u r/m16, or EDX:EAX = EAX *s/u r/m32 */ + /* EDX:EAX = EAX *s/u r/m32 */ struct { - Bool syned; - X86ScalarSz ssz; - X86RM* src; + Bool syned; + X86RM* src; } MulL; /* x86 div/idiv instruction. Modifies EDX and EAX and reads src. */ struct { - Bool syned; - X86ScalarSz ssz; - X86RM* src; + Bool syned; + X86RM* src; } Div; /* shld/shrd. op may only be Xsh_SHL or Xsh_SHR */ struct { @@ -539,12 +527,11 @@ typedef HReg src; HReg dst; } FpCMov; - /* Load/store the FPU's 16-bit control word (fldcw/fstcw) */ + /* Load the FPU's 16-bit control word (fldcw) */ struct { - Bool isLoad; X86AMode* addr; } - FpLdStCW; + FpLdCW; /* fstsw %ax */ struct { /* no fields */ @@ -568,7 +555,7 @@ typedef X86AMode* addr; } SseLdSt; struct { - Int sz; /* 4 or 8 only */ + UChar sz; /* 4 or 8 only */ HReg reg; X86AMode* addr; } SseLdzLO; @@ -616,11 +603,11 @@ typedef 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_Sh32 ( X86ShiftOp, UInt, X86RM* ); -extern X86Instr* X86Instr_Test32 ( X86RI* src, X86RM* dst ); -extern X86Instr* X86Instr_MulL ( Bool syned, X86ScalarSz, X86RM* ); -extern X86Instr* X86Instr_Div ( Bool syned, X86ScalarSz, X86RM* ); +extern X86Instr* X86Instr_Unary32 ( X86UnaryOp op, HReg dst ); +extern X86Instr* X86Instr_Sh32 ( X86ShiftOp, UInt, HReg ); +extern X86Instr* X86Instr_Test32 ( UInt imm32, HReg dst ); +extern X86Instr* X86Instr_MulL ( Bool syned, X86RM* ); +extern X86Instr* X86Instr_Div ( Bool syned, X86RM* ); extern X86Instr* X86Instr_Sh3232 ( X86ShiftOp, UInt amt, HReg src, HReg dst ); extern X86Instr* X86Instr_Push ( X86RMI* ); extern X86Instr* X86Instr_Call ( X86CondCode, Addr32, Int ); @@ -639,7 +626,7 @@ extern X86Instr* X86Instr_FpLdSt ( Bool isLoad, UChar sz, HReg reg, X86AMode* extern X86Instr* X86Instr_FpLdStI ( Bool isLoad, UChar sz, HReg reg, X86AMode* ); extern X86Instr* X86Instr_Fp64to32 ( HReg src, HReg dst ); extern X86Instr* X86Instr_FpCMov ( X86CondCode, HReg src, HReg dst ); -extern X86Instr* X86Instr_FpLdStCW ( Bool isLoad, X86AMode* ); +extern X86Instr* X86Instr_FpLdCW ( X86AMode* ); extern X86Instr* X86Instr_FpStSW_AX ( void ); extern X86Instr* X86Instr_FpCmp ( HReg srcL, HReg srcR, HReg dst ); diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index a431ed89a4..eaa78b332c 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -619,7 +619,7 @@ void set_FPU_rounding_default ( ISelEnv* env ) */ X86AMode* zero_esp = X86AMode_IR(0, hregX86_ESP()); addInstr(env, X86Instr_Push(X86RMI_Imm(DEFAULT_FPUCW))); - addInstr(env, X86Instr_FpLdStCW(True/*load*/, zero_esp)); + addInstr(env, X86Instr_FpLdCW(zero_esp)); add_to_esp(env, 4); } @@ -646,10 +646,10 @@ void set_FPU_rounding_mode ( ISelEnv* env, IRExpr* mode ) */ addInstr(env, mk_iMOVsd_RR(rrm, rrm2)); addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(3), rrm2)); - addInstr(env, X86Instr_Sh32(Xsh_SHL, 10, X86RM_Reg(rrm2))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 10, rrm2)); addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Imm(DEFAULT_FPUCW), rrm2)); addInstr(env, X86Instr_Push(X86RMI_Reg(rrm2))); - addInstr(env, X86Instr_FpLdStCW(True/*load*/, zero_esp)); + addInstr(env, X86Instr_FpLdCW(zero_esp)); add_to_esp(env, 4); } @@ -766,7 +766,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg dst = newVRegI(env); HReg reg = iselIntExpr_R(env, e->Iex.Binop.arg2); addInstr(env, mk_iMOVsd_RR(reg,dst)); - addInstr(env, X86Instr_Unary32(Xun_NEG,X86RM_Reg(dst))); + addInstr(env, X86Instr_Unary32(Xun_NEG,dst)); return dst; } @@ -844,12 +844,12 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) Xalu_AND, X86RMI_Imm(0xFFFF), dst)); break; case Iop_Sar8: - addInstr(env, X86Instr_Sh32(Xsh_SHL, 24, X86RM_Reg(dst))); - addInstr(env, X86Instr_Sh32(Xsh_SAR, 24, X86RM_Reg(dst))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 24, dst)); + addInstr(env, X86Instr_Sh32(Xsh_SAR, 24, dst)); break; case Iop_Sar16: - addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, X86RM_Reg(dst))); - addInstr(env, X86Instr_Sh32(Xsh_SAR, 16, X86RM_Reg(dst))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, dst)); + addInstr(env, X86Instr_Sh32(Xsh_SAR, 16, dst)); break; default: break; } @@ -864,15 +864,12 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) vassert(nshift >= 0); if (nshift > 0) /* Can't allow nshift==0 since that means %cl */ - addInstr(env, X86Instr_Sh32( - shOp, - nshift, - X86RM_Reg(dst))); + addInstr(env, X86Instr_Sh32( shOp, nshift, dst )); } else { /* General case; we have to force the amount into %cl. */ HReg regR = iselIntExpr_R(env, e->Iex.Binop.arg2); addInstr(env, mk_iMOVsd_RR(regR,hregX86_ECX())); - addInstr(env, X86Instr_Sh32(shOp, 0/* %cl */, X86RM_Reg(dst))); + addInstr(env, X86Instr_Sh32(shOp, 0/* %cl */, dst)); } return dst; } @@ -885,7 +882,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg lo8s = iselIntExpr_R(env, e->Iex.Binop.arg2); addInstr(env, mk_iMOVsd_RR(hi8s, hi8)); addInstr(env, mk_iMOVsd_RR(lo8s, lo8)); - addInstr(env, X86Instr_Sh32(Xsh_SHL, 8, X86RM_Reg(hi8))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 8, hi8)); addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(0xFF), lo8)); addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(lo8), hi8)); return hi8; @@ -898,7 +895,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg lo16s = iselIntExpr_R(env, e->Iex.Binop.arg2); addInstr(env, mk_iMOVsd_RR(hi16s, hi16)); addInstr(env, mk_iMOVsd_RR(lo16s, lo16)); - addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, X86RM_Reg(hi16))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, hi16)); addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(0xFFFF), lo16)); addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(lo16), hi16)); return hi16; @@ -919,10 +916,10 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) addInstr(env, mk_iMOVsd_RR(a16s, a16)); addInstr(env, mk_iMOVsd_RR(b16s, b16)); - addInstr(env, X86Instr_Sh32(Xsh_SHL, shift, X86RM_Reg(a16))); - addInstr(env, X86Instr_Sh32(Xsh_SHL, shift, X86RM_Reg(b16))); - addInstr(env, X86Instr_Sh32(shr_op, shift, X86RM_Reg(a16))); - addInstr(env, X86Instr_Sh32(shr_op, shift, X86RM_Reg(b16))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, shift, a16)); + addInstr(env, X86Instr_Sh32(Xsh_SHL, shift, b16)); + addInstr(env, X86Instr_Sh32(shr_op, shift, a16)); + addInstr(env, X86Instr_Sh32(shr_op, shift, b16)); addInstr(env, X86Instr_Alu32R(Xalu_MUL, X86RMI_Reg(a16), b16)); return b16; } @@ -934,7 +931,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) addInstr(env, X86Instr_FpCmp(fL,fR,dst)); /* shift this right 8 bits so as to conform to CmpF64 definition. */ - addInstr(env, X86Instr_Sh32(Xsh_SHR, 8, X86RM_Reg(dst))); + addInstr(env, X86Instr_Sh32(Xsh_SHR, 8, dst)); return dst; } @@ -1050,8 +1047,8 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); UInt amt = e->Iex.Unop.op==Iop_16Sto32 ? 16 : 24; addInstr(env, mk_iMOVsd_RR(src,dst) ); - addInstr(env, X86Instr_Sh32(Xsh_SHL, amt, X86RM_Reg(dst))); - addInstr(env, X86Instr_Sh32(Xsh_SAR, amt, X86RM_Reg(dst))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, amt, dst)); + addInstr(env, X86Instr_Sh32(Xsh_SAR, amt, dst)); return dst; } case Iop_Not8: @@ -1060,7 +1057,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg dst = newVRegI(env); HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); addInstr(env, mk_iMOVsd_RR(src,dst) ); - addInstr(env, X86Instr_Unary32(Xun_NOT,X86RM_Reg(dst))); + addInstr(env, X86Instr_Unary32(Xun_NOT,dst)); return dst; } case Iop_64HIto32: { @@ -1079,7 +1076,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); Int shift = e->Iex.Unop.op == Iop_16HIto8 ? 8 : 16; addInstr(env, mk_iMOVsd_RR(src,dst) ); - addInstr(env, X86Instr_Sh32(Xsh_SHR, shift, X86RM_Reg(dst))); + addInstr(env, X86Instr_Sh32(Xsh_SHR, shift, dst)); return dst; } case Iop_1Uto32: @@ -1096,8 +1093,8 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg dst = newVRegI(env); X86CondCode cond = iselCondCode(env, e->Iex.Unop.arg); addInstr(env, X86Instr_Set32(cond,dst)); - addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, X86RM_Reg(dst))); - addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(dst))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, dst)); + addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, dst)); return dst; } case Iop_Ctz32: { @@ -1217,7 +1214,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg dst = newVRegI(env); addInstr(env, mk_iMOVsd_RR(rX,dst)); r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond); - addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8))); + addInstr(env, X86Instr_Test32(0xFF, r8)); addInstr(env, X86Instr_CMov32(Xcc_Z,r0,dst)); return dst; } @@ -1357,7 +1354,11 @@ static X86RMI* iselIntExpr_RMI_wrk ( ISelEnv* env, IRExpr* e ) hregX86_EBP())); } - /* special case: load from memory */ + /* special case: 32-bit load from memory */ + if (e->tag == Iex_LDle && ty == Ity_I32) { + X86AMode* am = iselIntExpr_AMode(env, e->Iex.LDle.addr); + return X86RMI_Mem(am); + } /* default case: calculate into a register and return that */ { @@ -1518,8 +1519,8 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) unop(Iop_32to1,bind(0)) ); if (matchIRExpr(&mi,p_32to1,e)) { - X86RM* rm = iselIntExpr_RM(env, mi.bindee[0]); - addInstr(env, X86Instr_Test32(X86RI_Imm(1),rm)); + HReg r = iselIntExpr_R(env, mi.bindee[0]); + addInstr(env, X86Instr_Test32(1,r)); return Xcc_NZ; } @@ -1754,7 +1755,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) addInstr(env, mk_iMOVsd_RR(eXHi, tHi)); addInstr(env, mk_iMOVsd_RR(eXLo, tLo)); r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond); - addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8))); + addInstr(env, X86Instr_Test32(0xFF, r8)); /* This assumes the first cmov32 doesn't trash the condition codes, so they are still available for the second cmov32 */ addInstr(env, X86Instr_CMov32(Xcc_Z,X86RM_Reg(e0Hi),tHi)); @@ -1779,7 +1780,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) X86RM* rmLeft = iselIntExpr_RM(env, e->Iex.Binop.arg1); HReg rRight = iselIntExpr_R(env, e->Iex.Binop.arg2); addInstr(env, mk_iMOVsd_RR(rRight, hregX86_EAX())); - addInstr(env, X86Instr_MulL(syned, Xss_32, rmLeft)); + addInstr(env, X86Instr_MulL(syned, rmLeft)); /* Result is now in EDX:EAX. Tell the caller. */ addInstr(env, mk_iMOVsd_RR(hregX86_EDX(), tHi)); addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), tLo)); @@ -1801,7 +1802,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) iselInt64Expr(&sHi,&sLo, env, e->Iex.Binop.arg1); addInstr(env, mk_iMOVsd_RR(sHi, hregX86_EDX())); addInstr(env, mk_iMOVsd_RR(sLo, hregX86_EAX())); - addInstr(env, X86Instr_Div(syned, Xss_32, rmRight)); + addInstr(env, X86Instr_Div(syned, rmRight)); addInstr(env, mk_iMOVsd_RR(hregX86_EDX(), tHi)); addInstr(env, mk_iMOVsd_RR(hregX86_EAX(), tLo)); *rHi = tHi; @@ -1891,9 +1892,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) /* Ok. Now shift amt is in %ecx, and value is in tHi/tLo and those regs are legitimately modifiable. */ addInstr(env, X86Instr_Sh3232(Xsh_SHL, 0/*%cl*/, tLo, tHi)); - addInstr(env, X86Instr_Sh32(Xsh_SHL, 0/*%cl*/, X86RM_Reg(tLo))); - addInstr(env, X86Instr_Test32(X86RI_Imm(32), - X86RM_Reg(hregX86_ECX()))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 0/*%cl*/, tLo)); + addInstr(env, X86Instr_Test32(32, hregX86_ECX())); addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tLo), tHi)); addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(0), tTemp)); addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tTemp), tLo)); @@ -1934,9 +1934,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) /* Ok. Now shift amt is in %ecx, and value is in tHi/tLo and those regs are legitimately modifiable. */ addInstr(env, X86Instr_Sh3232(Xsh_SHR, 0/*%cl*/, tHi, tLo)); - addInstr(env, X86Instr_Sh32(Xsh_SHR, 0/*%cl*/, X86RM_Reg(tHi))); - addInstr(env, X86Instr_Test32(X86RI_Imm(32), - X86RM_Reg(hregX86_ECX()))); + addInstr(env, X86Instr_Sh32(Xsh_SHR, 0/*%cl*/, tHi)); + addInstr(env, X86Instr_Test32(32, hregX86_ECX())); addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tHi), tLo)); addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(0), tTemp)); addInstr(env, X86Instr_CMov32(Xcc_NZ, X86RM_Reg(tTemp), tHi)); @@ -2157,7 +2156,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); addInstr(env, mk_iMOVsd_RR(src,tHi)); addInstr(env, mk_iMOVsd_RR(src,tLo)); - addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(tHi))); + addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, tHi)); *rHi = tHi; *rLo = tLo; return; @@ -2203,8 +2202,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) HReg tHi = newVRegI(env); X86CondCode cond = iselCondCode(env, e->Iex.Unop.arg); addInstr(env, X86Instr_Set32(cond,tLo)); - addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, X86RM_Reg(tLo))); - addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(tLo))); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, tLo)); + addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, tLo)); addInstr(env, mk_iMOVsd_RR(tLo, tHi)); *rHi = tHi; *rLo = tLo; @@ -2219,8 +2218,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) iselInt64Expr(&sHi, &sLo, env, e->Iex.Unop.arg); addInstr(env, mk_iMOVsd_RR(sHi, tHi)); addInstr(env, mk_iMOVsd_RR(sLo, tLo)); - addInstr(env, X86Instr_Unary32(Xun_NOT,X86RM_Reg(tHi))); - addInstr(env, X86Instr_Unary32(Xun_NOT,X86RM_Reg(tLo))); + addInstr(env, X86Instr_Unary32(Xun_NOT,tHi)); + addInstr(env, X86Instr_Unary32(Xun_NOT,tLo)); *rHi = tHi; *rLo = tLo; return; @@ -2625,7 +2624,7 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) HReg r0 = iselDblExpr(env, e->Iex.Mux0X.expr0); HReg dst = newVRegF(env); addInstr(env, X86Instr_FpUnary(Xfp_MOV,rX,dst)); - addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8))); + addInstr(env, X86Instr_Test32(0xFF, r8)); addInstr(env, X86Instr_FpCMov(Xcc_Z,r0,dst)); return dst; } @@ -2759,7 +2758,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) for (i = 0; i < 4; i++) { am = X86AMode_IR(i*4, hregX86_ESP()); addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Mem(am), r32)); - addInstr(env, X86Instr_Unary32(Xun_NEG, X86RM_Reg(r32))); + addInstr(env, X86Instr_Unary32(Xun_NEG, r32)); addInstr(env, X86Instr_Alu32R(Xalu_SBB, X86RMI_Reg(r32), r32)); addInstr(env, X86Instr_Alu32M(Xalu_MOV, X86RI_Reg(r32), am)); } @@ -3124,7 +3123,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) HReg r0 = iselVecExpr(env, e->Iex.Mux0X.expr0); HReg dst = newVRegV(env); addInstr(env, mk_vMOVsd_RR(rX,dst)); - addInstr(env, X86Instr_Test32(X86RI_Imm(0xFF), X86RM_Reg(r8))); + addInstr(env, X86Instr_Test32(0xFF, r8)); addInstr(env, X86Instr_SseCMov(Xcc_Z,r0,dst)); return dst; }