PPC: Add support to call C functions and to return back to C.

Command line starts now, but it can't run any Lua code yet.
This commit is contained in:
Mike Pall 2010-08-31 00:29:38 +02:00
parent 690b1f3e4b
commit f4d4af1b6d

View File

@ -134,6 +134,11 @@
|
|//-----------------------------------------------------------------------
|
|// These basic macros should really be part of DynASM.
|.macro srwi, rx, ry, n; rlwinm rx, ry, 32-n, n, 31; .endmacro
|.macro slwi, rx, ry, n; rlwinm rx, ry, n, 0, 31-n; .endmacro
|.macro subi, rx, ry, i; addi rx, ry, -i; .endmacro
|
|// Trap for not-yet-implemented parts.
|.macro NYI; tw 4, sp, sp; .endmacro
|
@ -249,13 +254,52 @@ static void build_subroutines(BuildCtx *ctx)
|//-----------------------------------------------------------------------
|
|->vm_returnp:
| NYI
| // See vm_return. Also: TMP2 = previous base.
| andi. TMP0, PC, FRAME_P
| evsplati TMP1, LJ_TTRUE
| beq ->cont_dispatch
|
| // Return from pcall or xpcall fast func.
| lwz PC, FRAME_PC(TMP2) // Fetch PC of previous frame.
| mr BASE, TMP2 // Restore caller base.
| // Prepending may overwrite the pcall frame, so do it at the end.
| stwu TMP1, FRAME_PC(RA) // Prepend true to results.
|
|->vm_returnc:
| NYI
| andi. TMP0, PC, FRAME_TYPE
| addi RD, RD, 8 // RD = (nresults+1)*8.
| stw RD, SAVE_MULTRES
| beq ->BC_RET_Z // Handle regular return to Lua.
|
|->vm_return:
| NYI
| // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return
| // TMP0 = PC & FRAME_TYPE
| cmpwi TMP0, FRAME_C
| rlwinm TMP2, PC, 0, 0, 28
| li_vmstate C
| sub TMP2, BASE, TMP2 // TMP2 = previous base.
| bne ->vm_returnp
|
| addic. TMP1, RD, -8
| stw TMP2, L->base
| lwz TMP2, SAVE_NRES
| subi BASE, BASE, 8
| st_vmstate
| slwi TMP2, TMP2, 3
| beq >2
|1:
| addic. TMP1, TMP1, -8
| evldd TMP0, 0(RA)
| addi RA, RA, 8
| evstdd TMP0, 0(BASE)
| addi BASE, BASE, 8
| bne <1
|
|2:
| cmpw TMP2, RD // More/less results wanted?
| bne >6
|3:
| stw BASE, L->top // Store new top.
|
|->vm_leave_cp:
| lwz TMP0, SAVE_CFRAME // Restore previous C frame.
@ -266,6 +310,27 @@ static void build_subroutines(BuildCtx *ctx)
| restoreregs
| blr
|
|6:
| ble >7 // Less results wanted?
| // More results wanted. Check stack size and fill up results with nil.
| lwz TMP1, L->maxstack
| cmplw BASE, TMP1
| bge >8
| evstdd TISNIL, 0(BASE)
| addi RD, RD, 8
| addi BASE, BASE, 8
| b <2
|
|7: // Less results wanted.
| sub TMP0, RD, TMP2
| cmpwi TMP2, 0 // LUA_MULTRET+1 case?
| sub TMP0, BASE, TMP0 // Subtract the difference.
| iseleq BASE, BASE, TMP0 // Either keep top or shrink it.
| b <3
|
|8: // Corner case: need to grow stack for filling up results.
| NYI
|
|->vm_unwind_c: // Unwind C stack, return from vm_pcall.
| NYI
|->vm_unwind_c_eh: // Landing pad for external unwinder.
@ -986,6 +1051,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
break;
case BC_RET:
| NYI
|->BC_RET_Z:
| NYI
break;
@ -1077,7 +1144,36 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
case BC_FUNCC:
case BC_FUNCCW:
| NYI
| // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8
if (op == BC_FUNCC) {
| lwz TMP0, CFUNC:RB->f
} else {
| lwz TMP0, DISPATCH_GL(wrapf)(DISPATCH)
}
| add TMP1, RA, NARGS8:RC
| lwz TMP2, L->maxstack
| add RC, BASE, NARGS8:RC
| stw BASE, L->base
| mtctr TMP0
| cmplw TMP1, TMP2
| stw RC, L->top
| li_vmstate C
if (op == BC_FUNCCW) {
| lwz CARG2, CFUNC:RB->f
}
| mr CARG1, L
| bgt ->vm_growstack_c // Need to grow stack.
| st_vmstate
| bctrl // (lua_State *L [, lua_CFunction f])
| // Returns nresults.
| lwz TMP1, L->top
| slwi RD, CRET1, 3
| lwz BASE, L->base
| li_vmstate INTERP
| lwz PC, FRAME_PC(BASE) // Fetch PC of caller.
| sub RA, TMP1, RD // RA = L->top - nresults*8
| st_vmstate
| b ->vm_returnc
break;
/* ---------------------------------------------------------------------- */