aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-12-08 02:36:09 +0100
committerMike Pall <mike>2010-12-08 02:36:09 +0100
commit3ef6a53cfa95dbe890ec305368a7e446dbd5aedc (patch)
tree9546c3ba65bc6d9c2bcdd6cb6abfe8554a52322d /src
parentd778680098f630f4c74324f2fad27bb088d29d78 (diff)
downloadluajit-3ef6a53cfa95dbe890ec305368a7e446dbd5aedc.tar.gz
luajit-3ef6a53cfa95dbe890ec305368a7e446dbd5aedc.tar.bz2
luajit-3ef6a53cfa95dbe890ec305368a7e446dbd5aedc.zip
FFI: Turn cdata indexing into x86/x64 [base+idx*sz+ofs] addressing.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 6231f134..9c72a864 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1307,12 +1307,44 @@ static void asm_fusexref(ASMState *as, IRRef ref, RegSet allow)
1307 as->mrm.base = RID_NONE; 1307 as->mrm.base = RID_NONE;
1308 } else if (ir->o == IR_STRREF) { 1308 } else if (ir->o == IR_STRREF) {
1309 asm_fusestrref(as, ir, allow); 1309 asm_fusestrref(as, ir, allow);
1310 } else if (mayfuse(as, ref) && ir->o == IR_ADD &&
1311 asm_isk32(as, ir->op2, &as->mrm.ofs)) {
1312 /* NYI: gather index and shifts. */
1313 as->mrm.base = (uint8_t)ra_alloc1(as, ir->op1, allow);
1314 } else { 1310 } else {
1315 as->mrm.ofs = 0; 1311 as->mrm.ofs = 0;
1312 if (mayfuse(as, ref) && ir->o == IR_ADD && ra_noreg(ir->r)) {
1313 /* Gather (base+idx*sz)+ofs as emitted by cdata ptr/array indexing. */
1314 IRIns *irx;
1315 IRRef idx;
1316 Reg r;
1317 if (asm_isk32(as, ir->op2, &as->mrm.ofs)) { /* Recognize x+ofs. */
1318 ref = ir->op1;
1319 ir = IR(ref);
1320 if (!(ir->o == IR_ADD && mayfuse(as, ref) && ra_noreg(ir->r)))
1321 goto noadd;
1322 }
1323 as->mrm.scale = XM_SCALE1;
1324 idx = ir->op1;
1325 ref = ir->op2;
1326 irx = IR(idx);
1327 if (!(irx->o == IR_BSHL || irx->o == IR_ADD)) { /* Try other operand. */
1328 idx = ir->op2;
1329 ref = ir->op1;
1330 irx = IR(idx);
1331 }
1332 if (mayfuse(as, idx) && ra_noreg(irx->r)) {
1333 if (irx->o == IR_BSHL && irref_isk(irx->op2) && IR(irx->op2)->i <= 3) {
1334 /* Recognize idx<<b with b = 0-3, corresponding to sz = (1),2,4,8. */
1335 idx = irx->op1;
1336 as->mrm.scale = (uint8_t)(IR(irx->op2)->i << 6);
1337 } else if (irx->o == IR_ADD && irx->op1 == irx->op2) {
1338 /* FOLD does idx*2 ==> idx<<1 ==> idx+idx. */
1339 idx = irx->op1;
1340 as->mrm.scale = XM_SCALE2;
1341 }
1342 }
1343 r = ra_alloc1(as, idx, allow);
1344 rset_clear(allow, r);
1345 as->mrm.idx = (uint8_t)r;
1346 }
1347 noadd:
1316 as->mrm.base = (uint8_t)ra_alloc1(as, ref, allow); 1348 as->mrm.base = (uint8_t)ra_alloc1(as, ref, allow);
1317 } 1349 }
1318} 1350}