diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/buildvm_ppc.dasc | 104 |
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 | /* ---------------------------------------------------------------------- */ |
