PPC: Interpreter/JIT integration.

This commit is contained in:
Mike Pall 2011-09-05 18:34:38 +02:00
parent bab2f0efae
commit ae3317b186
2 changed files with 962 additions and 500 deletions

View File

@ -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
}

File diff suppressed because it is too large Load Diff