/* --------- 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";
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;
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 ) {
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 ) {
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:
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");
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);
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);
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());
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);
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;
}
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;
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;
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:
*(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:
/* --------- Instructions. --------- */
-/* --------- */
-typedef
- enum {
- Xss_16,
- Xss_32
- }
- X86ScalarSz;
-
-extern HChar* showX86ScalarSz ( X86ScalarSz );
-
-
/* --------- */
typedef
enum {
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 */
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 */
} 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 {
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 */
X86AMode* addr;
} SseLdSt;
struct {
- Int sz; /* 4 or 8 only */
+ UChar sz; /* 4 or 8 only */
HReg reg;
X86AMode* addr;
} SseLdzLO;
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 );
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 );
*/
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);
}
*/
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);
}
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;
}
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;
}
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;
}
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;
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;
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;
}
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;
}
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:
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: {
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:
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: {
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;
}
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 */
{
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;
}
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));
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));
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;
/* 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));
/* 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));
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;
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;
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;
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;
}
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));
}
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;
}