diff options
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 4f5610b0..c7527c15 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -1369,6 +1369,22 @@ static void asm_call(ASMState *as, IRIns *ir) | |||
1369 | asm_gencall(as, ci, args); | 1369 | asm_gencall(as, ci, args); |
1370 | } | 1370 | } |
1371 | 1371 | ||
1372 | /* -- Returns ------------------------------------------------------------- */ | ||
1373 | |||
1374 | /* Return to lower frame. Guard that it goes to the right spot. */ | ||
1375 | static void asm_retf(ASMState *as, IRIns *ir) | ||
1376 | { | ||
1377 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); | ||
1378 | void *pc = ir_kptr(IR(ir->op2)); | ||
1379 | int32_t delta = 1+bc_a(*((const BCIns *)pc - 1)); | ||
1380 | as->topslot -= (BCReg)delta; | ||
1381 | if ((int32_t)as->topslot < 0) as->topslot = 0; | ||
1382 | emit_setgl(as, base, jit_base); | ||
1383 | emit_addptr(as, base, -8*delta); | ||
1384 | asm_guardcc(as, CC_NE); | ||
1385 | emit_gmroi(as, XG_ARITHi(XOg_CMP), base, -4, ptr2addr(pc)); | ||
1386 | } | ||
1387 | |||
1372 | /* -- Type conversions ---------------------------------------------------- */ | 1388 | /* -- Type conversions ---------------------------------------------------- */ |
1373 | 1389 | ||
1374 | static void asm_tonum(ASMState *as, IRIns *ir) | 1390 | static void asm_tonum(ASMState *as, IRIns *ir) |
@@ -2795,14 +2811,14 @@ static void asm_head_base(ASMState *as) | |||
2795 | ** Stack overflow is rare, so let the regular exit handling fix this up. | 2811 | ** Stack overflow is rare, so let the regular exit handling fix this up. |
2796 | ** This is done in the context of the *parent* trace and parent exitno! | 2812 | ** This is done in the context of the *parent* trace and parent exitno! |
2797 | */ | 2813 | */ |
2798 | static void asm_checkstack(ASMState *as, RegSet allow) | 2814 | static void asm_checkstack(ASMState *as, BCReg topslot, RegSet allow) |
2799 | { | 2815 | { |
2800 | /* Try to get an unused temp. register, otherwise spill/restore eax. */ | 2816 | /* Try to get an unused temp. register, otherwise spill/restore eax. */ |
2801 | Reg r = allow ? rset_pickbot(allow) : RID_EAX; | 2817 | Reg r = allow ? rset_pickbot(allow) : RID_EAX; |
2802 | emit_jcc(as, CC_B, exitstub_addr(as->J, as->J->exitno)); | 2818 | emit_jcc(as, CC_B, exitstub_addr(as->J, as->J->exitno)); |
2803 | if (allow == RSET_EMPTY) /* Restore temp. register. */ | 2819 | if (allow == RSET_EMPTY) /* Restore temp. register. */ |
2804 | emit_rmro(as, XO_MOV, r, RID_ESP, sps_scale(SPS_TEMP1)); | 2820 | emit_rmro(as, XO_MOV, r, RID_ESP, sps_scale(SPS_TEMP1)); |
2805 | emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*as->topslot)); | 2821 | emit_gri(as, XG_ARITHi(XOg_CMP), r, (int32_t)(8*topslot)); |
2806 | emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE, ptr2addr(&J2G(as->J)->jit_base)); | 2822 | emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE, ptr2addr(&J2G(as->J)->jit_base)); |
2807 | emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack)); | 2823 | emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack)); |
2808 | emit_getgl(as, r, jit_L); | 2824 | emit_getgl(as, r, jit_L); |
@@ -2952,7 +2968,7 @@ static void asm_head_side(ASMState *as) | |||
2952 | 2968 | ||
2953 | /* Check Lua stack size if frames have been added. */ | 2969 | /* Check Lua stack size if frames have been added. */ |
2954 | if (as->topslot) | 2970 | if (as->topslot) |
2955 | asm_checkstack(as, allow & RSET_GPR); | 2971 | asm_checkstack(as, as->topslot, allow & RSET_GPR); |
2956 | } | 2972 | } |
2957 | 2973 | ||
2958 | /* -- Tail of trace ------------------------------------------------------- */ | 2974 | /* -- Tail of trace ------------------------------------------------------- */ |
@@ -3110,6 +3126,8 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
3110 | case IR_EQ: asm_comp(as, ir, CC_NE, CC_NE, VCC_P); break; | 3126 | case IR_EQ: asm_comp(as, ir, CC_NE, CC_NE, VCC_P); break; |
3111 | case IR_NE: asm_comp(as, ir, CC_E, CC_E, VCC_U|VCC_P); break; | 3127 | case IR_NE: asm_comp(as, ir, CC_E, CC_E, VCC_U|VCC_P); break; |
3112 | 3128 | ||
3129 | case IR_RETF: asm_retf(as, ir); break; | ||
3130 | |||
3113 | /* Bit ops. */ | 3131 | /* Bit ops. */ |
3114 | case IR_BNOT: asm_bitnot(as, ir); break; | 3132 | case IR_BNOT: asm_bitnot(as, ir); break; |
3115 | case IR_BSWAP: asm_bitswap(as, ir); break; | 3133 | case IR_BSWAP: asm_bitswap(as, ir); break; |