Browse Source

PPC: Interpreter/JIT integration.

Mike Pall 14 years ago
parent
commit
ae3317b186
2 changed files with 558 additions and 100 deletions
  1. 175 11
      src/buildvm_ppc.dasc
  2. 383 89
      src/buildvm_ppc.h

+ 175 - 11
src/buildvm_ppc.dasc

@@ -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
+ 383 - 89
src/buildvm_ppc.h


Some files were not shown because too many files changed in this diff