aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-08-31 00:29:38 +0200
committerMike Pall <mike>2010-08-31 00:29:38 +0200
commitf4d4af1b6d111d18a33611e72c4e904698986acd (patch)
tree189fc1b753034871601ba0987fd6dbf6387b7419 /src
parent690b1f3e4b103af73fb19dd32f84c6e68b34245c (diff)
downloadluajit-f4d4af1b6d111d18a33611e72c4e904698986acd.tar.gz
luajit-f4d4af1b6d111d18a33611e72c4e904698986acd.tar.bz2
luajit-f4d4af1b6d111d18a33611e72c4e904698986acd.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/buildvm_ppc.dasc104
1 files changed, 100 insertions, 4 deletions
diff --git a/src/buildvm_ppc.dasc b/src/buildvm_ppc.dasc
index ce049573..a2dda7a9 100644
--- a/src/buildvm_ppc.dasc
+++ b/src/buildvm_ppc.dasc
@@ -134,6 +134,11 @@
134| 134|
135|//----------------------------------------------------------------------- 135|//-----------------------------------------------------------------------
136| 136|
137|// These basic macros should really be part of DynASM.
138|.macro srwi, rx, ry, n; rlwinm rx, ry, 32-n, n, 31; .endmacro
139|.macro slwi, rx, ry, n; rlwinm rx, ry, n, 0, 31-n; .endmacro
140|.macro subi, rx, ry, i; addi rx, ry, -i; .endmacro
141|
137|// Trap for not-yet-implemented parts. 142|// Trap for not-yet-implemented parts.
138|.macro NYI; tw 4, sp, sp; .endmacro 143|.macro NYI; tw 4, sp, sp; .endmacro
139| 144|
@@ -249,13 +254,52 @@ static void build_subroutines(BuildCtx *ctx)
249 |//----------------------------------------------------------------------- 254 |//-----------------------------------------------------------------------
250 | 255 |
251 |->vm_returnp: 256 |->vm_returnp:
252 | NYI 257 | // See vm_return. Also: TMP2 = previous base.
258 | andi. TMP0, PC, FRAME_P
259 | evsplati TMP1, LJ_TTRUE
260 | beq ->cont_dispatch
261 |
262 | // Return from pcall or xpcall fast func.
263 | lwz PC, FRAME_PC(TMP2) // Fetch PC of previous frame.
264 | mr BASE, TMP2 // Restore caller base.
265 | // Prepending may overwrite the pcall frame, so do it at the end.
266 | stwu TMP1, FRAME_PC(RA) // Prepend true to results.
253 | 267 |
254 |->vm_returnc: 268 |->vm_returnc:
255 | NYI 269 | andi. TMP0, PC, FRAME_TYPE
270 | addi RD, RD, 8 // RD = (nresults+1)*8.
271 | stw RD, SAVE_MULTRES
272 | beq ->BC_RET_Z // Handle regular return to Lua.
256 | 273 |
257 |->vm_return: 274 |->vm_return:
258 | NYI 275 | // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return
276 | // TMP0 = PC & FRAME_TYPE
277 | cmpwi TMP0, FRAME_C
278 | rlwinm TMP2, PC, 0, 0, 28
279 | li_vmstate C
280 | sub TMP2, BASE, TMP2 // TMP2 = previous base.
281 | bne ->vm_returnp
282 |
283 | addic. TMP1, RD, -8
284 | stw TMP2, L->base
285 | lwz TMP2, SAVE_NRES
286 | subi BASE, BASE, 8
287 | st_vmstate
288 | slwi TMP2, TMP2, 3
289 | beq >2
290 |1:
291 | addic. TMP1, TMP1, -8
292 | evldd TMP0, 0(RA)
293 | addi RA, RA, 8
294 | evstdd TMP0, 0(BASE)
295 | addi BASE, BASE, 8
296 | bne <1
297 |
298 |2:
299 | cmpw TMP2, RD // More/less results wanted?
300 | bne >6
301 |3:
302 | stw BASE, L->top // Store new top.
259 | 303 |
260 |->vm_leave_cp: 304 |->vm_leave_cp:
261 | lwz TMP0, SAVE_CFRAME // Restore previous C frame. 305 | lwz TMP0, SAVE_CFRAME // Restore previous C frame.
@@ -266,6 +310,27 @@ static void build_subroutines(BuildCtx *ctx)
266 | restoreregs 310 | restoreregs
267 | blr 311 | blr
268 | 312 |
313 |6:
314 | ble >7 // Less results wanted?
315 | // More results wanted. Check stack size and fill up results with nil.
316 | lwz TMP1, L->maxstack
317 | cmplw BASE, TMP1
318 | bge >8
319 | evstdd TISNIL, 0(BASE)
320 | addi RD, RD, 8
321 | addi BASE, BASE, 8
322 | b <2
323 |
324 |7: // Less results wanted.
325 | sub TMP0, RD, TMP2
326 | cmpwi TMP2, 0 // LUA_MULTRET+1 case?
327 | sub TMP0, BASE, TMP0 // Subtract the difference.
328 | iseleq BASE, BASE, TMP0 // Either keep top or shrink it.
329 | b <3
330 |
331 |8: // Corner case: need to grow stack for filling up results.
332 | NYI
333 |
269 |->vm_unwind_c: // Unwind C stack, return from vm_pcall. 334 |->vm_unwind_c: // Unwind C stack, return from vm_pcall.
270 | NYI 335 | NYI
271 |->vm_unwind_c_eh: // Landing pad for external unwinder. 336 |->vm_unwind_c_eh: // Landing pad for external unwinder.
@@ -987,6 +1052,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
987 1052
988 case BC_RET: 1053 case BC_RET:
989 | NYI 1054 | NYI
1055 |->BC_RET_Z:
1056 | NYI
990 break; 1057 break;
991 1058
992 case BC_RET0: case BC_RET1: 1059 case BC_RET0: case BC_RET1:
@@ -1077,7 +1144,36 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
1077 1144
1078 case BC_FUNCC: 1145 case BC_FUNCC:
1079 case BC_FUNCCW: 1146 case BC_FUNCCW:
1080 | NYI 1147 | // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8
1148 if (op == BC_FUNCC) {
1149 | lwz TMP0, CFUNC:RB->f
1150 } else {
1151 | lwz TMP0, DISPATCH_GL(wrapf)(DISPATCH)
1152 }
1153 | add TMP1, RA, NARGS8:RC
1154 | lwz TMP2, L->maxstack
1155 | add RC, BASE, NARGS8:RC
1156 | stw BASE, L->base
1157 | mtctr TMP0
1158 | cmplw TMP1, TMP2
1159 | stw RC, L->top
1160 | li_vmstate C
1161 if (op == BC_FUNCCW) {
1162 | lwz CARG2, CFUNC:RB->f
1163 }
1164 | mr CARG1, L
1165 | bgt ->vm_growstack_c // Need to grow stack.
1166 | st_vmstate
1167 | bctrl // (lua_State *L [, lua_CFunction f])
1168 | // Returns nresults.
1169 | lwz TMP1, L->top
1170 | slwi RD, CRET1, 3
1171 | lwz BASE, L->base
1172 | li_vmstate INTERP
1173 | lwz PC, FRAME_PC(BASE) // Fetch PC of caller.
1174 | sub RA, TMP1, RD // RA = L->top - nresults*8
1175 | st_vmstate
1176 | b ->vm_returnc
1081 break; 1177 break;
1082 1178
1083 /* ---------------------------------------------------------------------- */ 1179 /* ---------------------------------------------------------------------- */