aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r--src/lj_asm.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 7773abe1..d26d0b4b 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1110,23 +1110,34 @@ static int noconflict(ASMState *as, IRRef ref, IROp conflict)
1110 return 1; /* Ok, no conflict. */ 1110 return 1; /* Ok, no conflict. */
1111} 1111}
1112 1112
1113/* Fuse array base into memory operand. */
1114static IRRef asm_fuseabase(ASMState *as, IRRef ref)
1115{
1116 IRIns *irb = IR(ref);
1117 as->mrm.ofs = 0;
1118 if (irb->o == IR_FLOAD) {
1119 IRIns *ira = IR(irb->op1);
1120 lua_assert(irb->op2 == IRFL_TAB_ARRAY);
1121 /* We can avoid the FLOAD of t->array for colocated arrays. */
1122 if (ira->o == IR_TNEW && ira->op1 <= LJ_MAX_COLOSIZE &&
1123 noconflict(as, irb->op1, IR_NEWREF)) {
1124 as->mrm.ofs = (int32_t)sizeof(GCtab); /* Ofs to colocated array. */
1125 return irb->op1; /* Table obj. */
1126 }
1127 } else if (irb->o == IR_ADD && irref_isk(irb->op2)) {
1128 /* Fuse base offset (vararg load). */
1129 as->mrm.ofs = IR(irb->op2)->i;
1130 return irb->op1;
1131 }
1132 return ref; /* Otherwise use the given array base. */
1133}
1134
1113/* Fuse array reference into memory operand. */ 1135/* Fuse array reference into memory operand. */
1114static void asm_fusearef(ASMState *as, IRIns *ir, RegSet allow) 1136static void asm_fusearef(ASMState *as, IRIns *ir, RegSet allow)
1115{ 1137{
1116 IRIns *irb = IR(ir->op1); 1138 IRIns *irx;
1117 IRIns *ira, *irx;
1118 lua_assert(ir->o == IR_AREF); 1139 lua_assert(ir->o == IR_AREF);
1119 lua_assert(irb->o == IR_FLOAD && irb->op2 == IRFL_TAB_ARRAY); 1140 as->mrm.base = (uint8_t)ra_alloc1(as, asm_fuseabase(as, ir->op1), allow);
1120 ira = IR(irb->op1);
1121 if (ira->o == IR_TNEW && ira->op1 <= LJ_MAX_COLOSIZE &&
1122 noconflict(as, irb->op1, IR_NEWREF)) {
1123 /* We can avoid the FLOAD of t->array for colocated arrays. */
1124 as->mrm.base = (uint8_t)ra_alloc1(as, irb->op1, allow); /* Table obj. */
1125 as->mrm.ofs = (int32_t)sizeof(GCtab); /* Ofs to colocated array. */
1126 } else {
1127 as->mrm.base = (uint8_t)ra_alloc1(as, ir->op1, allow); /* Array base. */
1128 as->mrm.ofs = 0;
1129 }
1130 irx = IR(ir->op2); 1141 irx = IR(ir->op2);
1131 if (irref_isk(ir->op2)) { 1142 if (irref_isk(ir->op2)) {
1132 as->mrm.ofs += 8*irx->i; 1143 as->mrm.ofs += 8*irx->i;
@@ -1277,10 +1288,10 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
1277 } else if (mayfuse(as, ref)) { 1288 } else if (mayfuse(as, ref)) {
1278 RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR; 1289 RegSet xallow = (allow & RSET_GPR) ? allow : RSET_GPR;
1279 if (ir->o == IR_SLOAD) { 1290 if (ir->o == IR_SLOAD) {
1280 if (!irt_isint(ir->t) && !(ir->op2 & IRSLOAD_PARENT) && 1291 if ((!irt_isint(ir->t) || (ir->op2 & IRSLOAD_FRAME)) &&
1281 noconflict(as, ref, IR_RETF)) { 1292 !(ir->op2 & IRSLOAD_PARENT) && noconflict(as, ref, IR_RETF)) {
1282 as->mrm.base = (uint8_t)ra_alloc1(as, REF_BASE, xallow); 1293 as->mrm.base = (uint8_t)ra_alloc1(as, REF_BASE, xallow);
1283 as->mrm.ofs = 8*((int32_t)ir->op1-1); 1294 as->mrm.ofs = 8*((int32_t)ir->op1-1) + ((ir->op2&IRSLOAD_FRAME)?4:0);
1284 as->mrm.idx = RID_NONE; 1295 as->mrm.idx = RID_NONE;
1285 return RID_MRM; 1296 return RID_MRM;
1286 } 1297 }
@@ -2031,7 +2042,7 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
2031 2042
2032static void asm_sload(ASMState *as, IRIns *ir) 2043static void asm_sload(ASMState *as, IRIns *ir)
2033{ 2044{
2034 int32_t ofs = 8*((int32_t)ir->op1-1); 2045 int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0);
2035 IRType1 t = ir->t; 2046 IRType1 t = ir->t;
2036 Reg base; 2047 Reg base;
2037 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ 2048 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
@@ -2056,7 +2067,7 @@ static void asm_sload(ASMState *as, IRIns *ir)
2056 Reg dest = ra_dest(as, ir, allow); 2067 Reg dest = ra_dest(as, ir, allow);
2057 base = ra_alloc1(as, REF_BASE, RSET_GPR); 2068 base = ra_alloc1(as, REF_BASE, RSET_GPR);
2058 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t)); 2069 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
2059 if (irt_isint(t)) 2070 if (irt_isint(t) && !(ir->op2 & IRSLOAD_FRAME))
2060 emit_rmro(as, XO_CVTSD2SI, dest, base, ofs); 2071 emit_rmro(as, XO_CVTSD2SI, dest, base, ofs);
2061 else if (irt_isnum(t)) 2072 else if (irt_isnum(t))
2062 emit_rmro(as, XMM_MOVRM(as), dest, base, ofs); 2073 emit_rmro(as, XMM_MOVRM(as), dest, base, ofs);