Support all kinds of XLOAD/XSTORE references in backend.

Fuse pointer arithmetic, too.
This commit is contained in:
Mike Pall 2010-12-06 03:09:52 +01:00
parent a850b27da9
commit b56b83487f

View File

@ -1297,14 +1297,21 @@ static void asm_fusestrref(ASMState *as, IRIns *ir, RegSet allow)
}
}
static void asm_fusexref(ASMState *as, IRIns *ir, RegSet allow)
static void asm_fusexref(ASMState *as, IRRef ref, RegSet allow)
{
IRIns *ir = IR(ref);
if (ir->o == IR_KPTR) {
as->mrm.ofs = ir->i;
as->mrm.base = as->mrm.idx = RID_NONE;
} else {
lua_assert(ir->o == IR_STRREF);
} else if (ir->o == IR_STRREF) {
asm_fusestrref(as, ir, allow);
} else if (mayfuse(as, ref) && ir->o == IR_ADD &&
asm_isk32(as, ir->op2, &as->mrm.ofs)) {
/* NYI: gather index and shifts. */
as->mrm.idx = RID_NONE;
as->mrm.base = (uint8_t)ra_alloc1(as, ir->op1, allow);
} else {
as->mrm.base = (uint8_t)ra_alloc1(as, ref, allow);
}
}
@ -1360,7 +1367,7 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
*/
if ((irt_isint(ir->t) || irt_isaddr(ir->t)) &&
noconflict(as, ref, IR_XSTORE)) {
asm_fusexref(as, IR(ir->op1), xallow);
asm_fusexref(as, ir->op1, xallow);
return RID_MRM;
}
} else if (ir->o == IR_VLOAD) {
@ -1962,7 +1969,7 @@ static void asm_fxload(ASMState *as, IRIns *ir)
if (ir->o == IR_FLOAD)
asm_fusefref(as, ir, RSET_GPR);
else
asm_fusexref(as, IR(ir->op1), RSET_GPR);
asm_fusexref(as, ir->op1, RSET_GPR);
/* ir->op2 is ignored -- unaligned loads are ok on x86. */
switch (irt_type(ir->t)) {
case IRT_I8: xo = XO_MOVSXb; break;
@ -1996,7 +2003,7 @@ static void asm_fxstore(ASMState *as, IRIns *ir)
if (ir->o == IR_FSTORE)
asm_fusefref(as, IR(ir->op1), allow);
else
asm_fusexref(as, IR(ir->op1), allow);
asm_fusexref(as, ir->op1, allow);
/* ir->op2 is ignored -- unaligned stores are ok on x86. */
if (ra_hasreg(src)) {
x86Op xo;