aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-02-03 04:13:51 +0100
committerMike Pall <mike>2011-02-03 04:22:27 +0100
commitdf65b8b419c12327254dec0df116c62525aaabad (patch)
treeb4ba6ea2841692123b49b3033420dbb7282cbcd6 /src/lj_asm.c
parent1027018b2135caf45057c3d3b3da03ffb0c6add3 (diff)
downloadluajit-df65b8b419c12327254dec0df116c62525aaabad.tar.gz
luajit-df65b8b419c12327254dec0df116c62525aaabad.tar.bz2
luajit-df65b8b419c12327254dec0df116c62525aaabad.zip
FFI: Rename IR_CNEWP to IR_CNEWI and use it to box 64 bit integers.
Generates smaller IR and DCE eliminates many intermediate boxes. Needs allocation sinking to eliminate the boxes kept alive by PHIs.
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r--src/lj_asm.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 8864c9a3..77b55f0c 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -2518,7 +2518,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)
2518{ 2518{
2519 CTState *cts = ctype_ctsG(J2G(as->J)); 2519 CTState *cts = ctype_ctsG(J2G(as->J));
2520 CTypeID typeid = (CTypeID)IR(ir->op1)->i; 2520 CTypeID typeid = (CTypeID)IR(ir->op1)->i;
2521 CTSize sz = (ir->o == IR_CNEWP || ir->op2 == REF_NIL) ? 2521 CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ?
2522 lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i; 2522 lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i;
2523 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; 2523 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
2524 IRRef args[2]; 2524 IRRef args[2];
@@ -2529,33 +2529,45 @@ static void asm_cnew(ASMState *as, IRIns *ir)
2529 as->gcsteps++; 2529 as->gcsteps++;
2530 asm_setupresult(as, ir, ci); /* GCcdata * */ 2530 asm_setupresult(as, ir, ci); /* GCcdata * */
2531 2531
2532 /* Initialize pointer cdata object. */ 2532 /* Initialize immutable cdata object. */
2533 if (ir->o == IR_CNEWP) { 2533 if (ir->o == IR_CNEWI) {
2534 RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
2535#if LJ_64
2536 Reg r64 = sz == 8 ? REX_64 : 0;
2534 if (irref_isk(ir->op2)) { 2537 if (irref_isk(ir->op2)) {
2535 IRIns *irk = IR(ir->op2); 2538 IRIns *irk = IR(ir->op2);
2536#if LJ_64 2539 uint64_t k = irk->o == IR_KINT64 ? ir_k64(irk)->u64 :
2537 if (irk->o == IR_KINT64) { 2540 (uint64_t)(uint32_t)irk->i;
2538 uint64_t k = ir_k64(irk)->u64; 2541 if (sz == 4 || checki32((int64_t)k)) {
2539 lua_assert(sz == 8); 2542 emit_i32(as, (int32_t)k);
2540 if (checki32((int64_t)k)) { 2543 emit_rmro(as, XO_MOVmi, r64, RID_RET, sizeof(GCcdata));
2541 emit_i32(as, (int32_t)k);
2542 emit_rmro(as, XO_MOVmi, REX_64, RID_RET, sizeof(GCcdata));
2543 } else {
2544 emit_movtomro(as, RID_ECX|REX_64, RID_RET, sizeof(GCcdata));
2545 emit_loadu64(as, RID_ECX, k);
2546 }
2547 } else { 2544 } else {
2548#endif 2545 emit_movtomro(as, RID_ECX + r64, RID_RET, sizeof(GCcdata));
2549 lua_assert(sz == 4); 2546 emit_loadu64(as, RID_ECX, k);
2550 emit_movmroi(as, RID_RET, sizeof(GCcdata), irk->i);
2551#if LJ_64
2552 } 2547 }
2553#endif
2554 } else { 2548 } else {
2555 Reg r = ra_alloc1(as, ir->op2, (RSET_GPR & ~RSET_SCRATCH)); 2549 Reg r = ra_alloc1(as, ir->op2, allow);
2556 emit_movtomro(as, r + ((LJ_64 && sz == 8) ? REX_64 : 0), 2550 emit_movtomro(as, r + r64, RID_RET, sizeof(GCcdata));
2557 RID_RET, sizeof(GCcdata)); 2551 }
2552#else
2553 int32_t ofs = sizeof(GCcdata);
2554 if (LJ_HASFFI && sz == 8) {
2555 ofs += 4; ir++;
2556 lua_assert(ir->o == IR_HIOP);
2558 } 2557 }
2558 do {
2559 if (irref_isk(ir->op2)) {
2560 emit_movmroi(as, RID_RET, ofs, IR(ir->op2)->i);
2561 } else {
2562 Reg r = ra_alloc1(as, ir->op2, allow);
2563 emit_movtomro(as, r, RID_RET, ofs);
2564 rset_clear(allow, r);
2565 }
2566 if (!LJ_HASFFI || ofs == sizeof(GCcdata)) break;
2567 ofs -= 4; ir--;
2568 } while (1);
2569#endif
2570 lua_assert(sz == 4 || (sz == 8 && (LJ_64 || LJ_HASFFI)));
2559 } 2571 }
2560 2572
2561 /* Combine initialization of marked, gct and typeid. */ 2573 /* Combine initialization of marked, gct and typeid. */
@@ -3289,6 +3301,9 @@ static void asm_hiop(ASMState *as, IRIns *ir)
3289 if (!uselo) 3301 if (!uselo)
3290 ra_allocref(as, ir->op1, RID2RSET(RID_RET)); /* Mark call as used. */ 3302 ra_allocref(as, ir->op1, RID2RSET(RID_RET)); /* Mark call as used. */
3291 break; 3303 break;
3304 case IR_CNEWI:
3305 /* Nothing to do here. Handled by CNEWI itself. */
3306 break;
3292 default: lua_assert(0); break; 3307 default: lua_assert(0); break;
3293 } 3308 }
3294#else 3309#else
@@ -4057,7 +4072,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
4057 case IR_SNEW: asm_snew(as, ir); break; 4072 case IR_SNEW: asm_snew(as, ir); break;
4058 case IR_TNEW: asm_tnew(as, ir); break; 4073 case IR_TNEW: asm_tnew(as, ir); break;
4059 case IR_TDUP: asm_tdup(as, ir); break; 4074 case IR_TDUP: asm_tdup(as, ir); break;
4060 case IR_CNEW: case IR_CNEWP: asm_cnew(as, ir); break; 4075 case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
4061 4076
4062 /* Write barriers. */ 4077 /* Write barriers. */
4063 case IR_TBAR: asm_tbar(as, ir); break; 4078 case IR_TBAR: asm_tbar(as, ir); break;
@@ -4164,8 +4179,10 @@ static void asm_setup_regsp(ASMState *as, GCtrace *T)
4164 } 4179 }
4165#if LJ_32 && LJ_HASFFI 4180#if LJ_32 && LJ_HASFFI
4166 case IR_HIOP: 4181 case IR_HIOP:
4167 if ((ir-1)->o == IR_CALLN) 4182 if ((ir-1)->o == IR_CALLN) {
4168 ir->prev = REGSP_HINT(RID_RETHI); 4183 ir->prev = REGSP_HINT(RID_RETHI);
4184 continue;
4185 }
4169 break; 4186 break;
4170#endif 4187#endif
4171 /* C calls evict all scratch regs and return results in RID_RET. */ 4188 /* C calls evict all scratch regs and return results in RID_RET. */
@@ -4174,7 +4191,7 @@ static void asm_setup_regsp(ASMState *as, GCtrace *T)
4174 if (as->evenspill < 3) /* lj_str_new and lj_tab_newkey need 3 args. */ 4191 if (as->evenspill < 3) /* lj_str_new and lj_tab_newkey need 3 args. */
4175 as->evenspill = 3; 4192 as->evenspill = 3;
4176#endif 4193#endif
4177 case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWP: case IR_TOSTR: 4194 case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR:
4178 ir->prev = REGSP_HINT(RID_RET); 4195 ir->prev = REGSP_HINT(RID_RET);
4179 if (inloop) 4196 if (inloop)
4180 as->modset = RSET_SCRATCH; 4197 as->modset = RSET_SCRATCH;