|
@@ -16,7 +16,7 @@
|
|
|
|//-----------------------------------------------------------------------
|
|
|
|
|
|
|
|// Fixed register assignments for the interpreter.
|
|
|
-|// Don't use: r1 = sp, r2 and r13 = reserved and/or small data area ptr
|
|
|
+|// Don't use: r1 = sp, r2 and r13 = reserved (TOC, TLS or SDATA)
|
|
|
|
|
|
|
|// The following must be C callee-save (but BASE is often refetched).
|
|
|
|.define BASE, r14 // Base of current Lua stack frame.
|
|
@@ -25,6 +25,8 @@
|
|
|
|.define DISPATCH, r17 // Opcode dispatch table.
|
|
|
|.define LREG, r18 // Register holding lua_State (also in SAVE_L).
|
|
|
|.define MULTRES, r19 // Size of multi-result: (nresults+1)*8.
|
|
|
+|.define JGL, r30 // On-trace: global_State + 32768.
|
|
|
+|.define JTR, r31 // On-trace: trace number.
|
|
|
|
|
|
|
|// Constants for type-comparisons, stores and conversions. C callee-save.
|
|
|
|.define TISNUM, r22
|
|
@@ -267,12 +269,21 @@
|
|
|
|
|
|
|
#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
|
|
|
|
|
|
|
+|.macro hotcheck, delta, target
|
|
|
+| rlwinm TMP1, PC, 31, 25, 30
|
|
|
+| addi TMP1, TMP1, GG_DISP2HOT
|
|
|
+| lhzx TMP2, DISPATCH, TMP1
|
|
|
+| addic. TMP2, TMP2, -delta
|
|
|
+| sthx TMP2, DISPATCH, TMP1
|
|
|
+| blt target
|
|
|
+|.endmacro
|
|
|
+|
|
|
|
|.macro hotloop
|
|
|
-| NYI
|
|
|
+| hotcheck HOTCOUNT_LOOP, ->vm_hotloop
|
|
|
|.endmacro
|
|
|
|
|
|
|
|.macro hotcall
|
|
|
-| NYI
|
|
|
+| hotcheck HOTCOUNT_CALL, ->vm_hotcall
|
|
|
|.endmacro
|
|
|
|
|
|
|
|// Set current VM state. Uses TMP0.
|
|
@@ -2202,7 +2213,18 @@ static void build_subroutines(BuildCtx *ctx)
|
|
|
|
|
|
|
|->vm_record: // Dispatch target for recording phase.
|
|
|
#if LJ_HASJIT
|
|
|
- | NYI
|
|
|
+ | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
|
|
|
+ | andi. TMP0, TMP3, HOOK_VMEVENT // No recording while in vmevent.
|
|
|
+ | bne >5
|
|
|
+ | // Decrement the hookcount for consistency, but always do the call.
|
|
|
+ | lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH)
|
|
|
+ | andi. TMP0, TMP3, HOOK_ACTIVE
|
|
|
+ | bne >1
|
|
|
+ | subi TMP2, TMP2, 1
|
|
|
+ | andi. TMP0, TMP3, LUA_MASKLINE|LUA_MASKCOUNT
|
|
|
+ | beqy >1
|
|
|
+ | stw TMP2, DISPATCH_GL(hookcount)(DISPATCH)
|
|
|
+ | b >1
|
|
|
#endif
|
|
|
|
|
|
|
|->vm_rethook: // Dispatch target for return hooks.
|
|
@@ -2256,7 +2278,19 @@ static void build_subroutines(BuildCtx *ctx)
|
|
|
|
|
|
|
|->vm_hotloop: // Hot loop counter underflow.
|
|
|
#if LJ_HASJIT
|
|
|
- | NYI
|
|
|
+ | lwz LFUNC:TMP1, FRAME_FUNC(BASE)
|
|
|
+ | addi CARG1, DISPATCH, GG_DISP2J
|
|
|
+ | stw PC, SAVE_PC
|
|
|
+ | lwz TMP1, LFUNC:TMP1->pc
|
|
|
+ | mr CARG2, PC
|
|
|
+ | stw L, DISPATCH_J(L)(DISPATCH)
|
|
|
+ | lbz TMP1, PC2PROTO(framesize)(TMP1)
|
|
|
+ | stw BASE, L->base
|
|
|
+ | slwi TMP1, TMP1, 3
|
|
|
+ | add TMP1, BASE, TMP1
|
|
|
+ | stw TMP1, L->top
|
|
|
+ | bl extern lj_trace_hot // (jit_State *J, const BCIns *pc)
|
|
|
+ | b <3
|
|
|
#endif
|
|
|
|
|
|
|
|->vm_callhook: // Dispatch target for call hooks.
|
|
@@ -2291,13 +2325,111 @@ static void build_subroutines(BuildCtx *ctx)
|
|
|
|//-- Trace exit handler -------------------------------------------------
|
|
|
|//-----------------------------------------------------------------------
|
|
|
|
|
|
|
+ |.macro savex_, a, b, c, d
|
|
|
+ | stfd f..a, 16+a*8(sp)
|
|
|
+ | stfd f..b, 16+b*8(sp)
|
|
|
+ | stfd f..c, 16+c*8(sp)
|
|
|
+ | stfd f..d, 16+d*8(sp)
|
|
|
+ |.endmacro
|
|
|
+ |
|
|
|
|->vm_exit_handler:
|
|
|
#if LJ_HASJIT
|
|
|
- | NYI
|
|
|
+ | addi sp, sp, -(16+32*8+32*4)
|
|
|
+ | stmw r2, 16+32*8+2*4(sp)
|
|
|
+ | addi DISPATCH, JGL, -GG_DISP2G-32768
|
|
|
+ | li CARG2, ~LJ_VMST_EXIT
|
|
|
+ | lwz CARG1, 16+32*8+32*4(sp) // Get stack chain.
|
|
|
+ | stw CARG2, DISPATCH_GL(vmstate)(DISPATCH)
|
|
|
+ | savex_ 0,1,2,3
|
|
|
+ | stw CARG1, 0(sp) // Store extended stack chain.
|
|
|
+ | mcrxr cr0 // Clear SO flag.
|
|
|
+ | savex_ 4,5,6,7
|
|
|
+ | addi CARG2, sp, 16+32*8+32*4 // Recompute original value of sp.
|
|
|
+ | savex_ 8,9,10,11
|
|
|
+ | stw CARG2, 16+32*8+1*4(sp) // Store sp in RID_SP.
|
|
|
+ | savex_ 12,13,14,15
|
|
|
+ | mflr CARG3
|
|
|
+ | li TMP1, 0
|
|
|
+ | savex_ 16,17,18,19
|
|
|
+ | stw TMP1, 16+32*8+0*4(sp) // Clear RID_TMP.
|
|
|
+ | savex_ 20,21,22,23
|
|
|
+ | lwz CARG4, 0(CARG3) // Load exit stub group offset.
|
|
|
+ | savex_ 24,25,26,27
|
|
|
+ | lwz L, DISPATCH_GL(jit_L)(DISPATCH)
|
|
|
+ | savex_ 28,29,30,31
|
|
|
+ | sub CARG3, TMP0, CARG3 // Compute exit number.
|
|
|
+ | lwz BASE, DISPATCH_GL(jit_base)(DISPATCH)
|
|
|
+ | srwi CARG3, CARG3, 2
|
|
|
+ | stw L, DISPATCH_J(L)(DISPATCH)
|
|
|
+ | subi CARG3, CARG3, 2
|
|
|
+ | stw TMP1, DISPATCH_GL(jit_L)(DISPATCH)
|
|
|
+ | add CARG3, CARG4, CARG3
|
|
|
+ | stw BASE, L->base
|
|
|
+ | addi CARG1, DISPATCH, GG_DISP2J
|
|
|
+ | stw CARG3, DISPATCH_J(exitno)(DISPATCH)
|
|
|
+ | addi CARG2, sp, 16
|
|
|
+ | stw JTR, DISPATCH_J(parent)(DISPATCH)
|
|
|
+ | bl extern lj_trace_exit // (jit_State *J, ExitState *ex)
|
|
|
+ | // Returns MULTRES (unscaled) or negated error code.
|
|
|
+ | lwz TMP1, L->cframe
|
|
|
+ | lwz TMP2, 0(sp)
|
|
|
+ | lwz BASE, L->base
|
|
|
+ | rlwinm sp, TMP1, 0, 0, 29
|
|
|
+ | lwz PC, SAVE_PC // Get SAVE_PC.
|
|
|
+ | stw TMP2, 0(sp)
|
|
|
+ | stw L, SAVE_L // Set SAVE_L (on-trace resume/yield).
|
|
|
+ | b >1
|
|
|
#endif
|
|
|
|->vm_exit_interp:
|
|
|
#if LJ_HASJIT
|
|
|
- | NYI
|
|
|
+ | // CARG1 = MULTRES or negated error code, BASE, PC and JGL set.
|
|
|
+ | lwz L, SAVE_L
|
|
|
+ | addi DISPATCH, JGL, -GG_DISP2G-32768
|
|
|
+ |1:
|
|
|
+ | cmpwi CARG1, 0
|
|
|
+ | blt >3 // Check for error from exit.
|
|
|
+ | lwz LFUNC:TMP1, FRAME_FUNC(BASE)
|
|
|
+ | slwi MULTRES, CARG1, 3
|
|
|
+ | li TMP2, 0
|
|
|
+ | stw MULTRES, SAVE_MULTRES
|
|
|
+ | lwz TMP1, LFUNC:TMP1->pc
|
|
|
+ | stw TMP2, DISPATCH_GL(jit_L)(DISPATCH)
|
|
|
+ | lwz KBASE, PC2PROTO(k)(TMP1)
|
|
|
+ | // Setup type comparison constants.
|
|
|
+ | li TISNUM, LJ_TISNUM
|
|
|
+ | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
|
|
+ | stw TMP3, TMPD
|
|
|
+ | li ZERO, 0
|
|
|
+ | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float).
|
|
|
+ | lfs TOBIT, TMPD
|
|
|
+ | stw TMP3, TMPD
|
|
|
+ | lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double)
|
|
|
+ | li TISNIL, LJ_TNIL
|
|
|
+ | stw TMP0, TONUM_HI
|
|
|
+ | lfs TONUM, TMPD
|
|
|
+ | // Modified copy of ins_next which handles function header dispatch, too.
|
|
|
+ | lwz INS, 0(PC)
|
|
|
+ | addi PC, PC, 4
|
|
|
+ | // Assumes TISNIL == ~LJ_VMST_INTERP == -1.
|
|
|
+ | stw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
|
|
|
+ | decode_OP4 TMP1, INS
|
|
|
+ | decode_RA8 RA, INS
|
|
|
+ | lwzx TMP0, DISPATCH, TMP1
|
|
|
+ | mtctr TMP0
|
|
|
+ | cmpwi TMP1, BC_FUNCF*4 // Function header?
|
|
|
+ | beq >2
|
|
|
+ | decode_RB8 RB, INS
|
|
|
+ | decode_RD8 RD, INS
|
|
|
+ | decode_RC8 RC, INS
|
|
|
+ | bctr
|
|
|
+ |2:
|
|
|
+ | add RA, RA, BASE
|
|
|
+ | bctr
|
|
|
+ |
|
|
|
+ |3: // Rethrow error from the right C frame.
|
|
|
+ | neg CARG2, CARG1
|
|
|
+ | mr CARG1, L
|
|
|
+ | bl extern lj_err_throw // (lua_State *L, int errcode)
|
|
|
#endif
|
|
|
|
|
|
|
|//-----------------------------------------------------------------------
|
|
@@ -2368,7 +2500,24 @@ static void build_subroutines(BuildCtx *ctx)
|
|
|
|1:
|
|
|
| fabs FARG1, FARG1; blr
|
|
|
|2:
|
|
|
+#if LJ_HASJIT
|
|
|
+ | cmplwi CARG1, 9; beq >9; bgt >2
|
|
|
+ | b extern atan2
|
|
|
+ | // No support needed for IR_LDEXP.
|
|
|
+ |2:
|
|
|
+ | cmplwi CARG1, 11; bgt >9
|
|
|
+ | fsub f0, FARG1, FARG2
|
|
|
+ | beq >1
|
|
|
+ | fsel FARG1, f0, FARG2, FARG1 // IR_MAX
|
|
|
+ | blr
|
|
|
+ |1:
|
|
|
+ | fsel FARG1, f0, FARG1, FARG2 // IR_MIN
|
|
|
+ | blr
|
|
|
+ |9:
|
|
|
+ | NYI // Bad op.
|
|
|
+#else
|
|
|
| NYI // Other operations only needed by JIT compiler.
|
|
|
+#endif
|
|
|
|
|
|
|
|//-----------------------------------------------------------------------
|
|
|
|//-- Miscellaneous functions --------------------------------------------
|
|
@@ -4309,7 +4458,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|
|
| lwz TMP2, 4(RA)
|
|
|
| checknil TMP1; beq >1 // Stop if iterator returned nil.
|
|
|
if (op == BC_JITERL) {
|
|
|
- | NYI
|
|
|
+ | stw TMP1, -8(RA)
|
|
|
+ | stw TMP2, -4(RA)
|
|
|
+ | b =>BC_JLOOP
|
|
|
} else {
|
|
|
| branch_RD // Otherwise save control var + branch.
|
|
|
| stw TMP1, -8(RA)
|
|
@@ -4336,7 +4487,17 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|
|
|
|
|
case BC_JLOOP:
|
|
|
#if LJ_HASJIT
|
|
|
- | NYI
|
|
|
+ | // RA = base*8 (ignored), RD = traceno*8
|
|
|
+ | lwz TMP1, DISPATCH_J(trace)(DISPATCH)
|
|
|
+ | srwi RD, RD, 1
|
|
|
+ | lwzx TRACE:TMP2, TMP1, RD
|
|
|
+ | mcrxr cr0 // Clear SO flag.
|
|
|
+ | lwz TMP2, TRACE:TMP2->mcode
|
|
|
+ | stw BASE, DISPATCH_GL(jit_base)(DISPATCH)
|
|
|
+ | mtctr TMP2
|
|
|
+ | stw L, DISPATCH_GL(jit_L)(DISPATCH)
|
|
|
+ | addi JGL, DISPATCH, GG_DISP2G+32768
|
|
|
+ | bctr
|
|
|
#endif
|
|
|
break;
|
|
|
|
|
@@ -4368,12 +4529,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|
|
| cmplw RA, TMP2
|
|
|
| slwi TMP1, TMP1, 3
|
|
|
| bgt ->vm_growstack_l
|
|
|
- | ins_next1
|
|
|
+ if (op != BC_JFUNCF) {
|
|
|
+ | ins_next1
|
|
|
+ }
|
|
|
|2:
|
|
|
| cmplw NARGS8:RC, TMP1 // Check for missing parameters.
|
|
|
| ble >3
|
|
|
if (op == BC_JFUNCF) {
|
|
|
- | NYI
|
|
|
+ | decode_RD8 RD, INS
|
|
|
+ | b =>BC_JLOOP
|
|
|
} else {
|
|
|
| ins_next2
|
|
|
}
|