diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/buildvm_arm.dasc | 151 |
1 files changed, 141 insertions, 10 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index 37fe7e3b..fc2f017b 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc | |||
| @@ -163,6 +163,12 @@ | |||
| 163 | | | 163 | | |
| 164 | |//----------------------------------------------------------------------- | 164 | |//----------------------------------------------------------------------- |
| 165 | | | 165 | | |
| 166 | |// Macros to test operand types. | ||
| 167 | |.macro checktp, reg, tp; cmn reg, #-tp; .endmacro | ||
| 168 | |.macro checkstr, reg, target; checktp reg, LJ_TSTR; bne target; .endmacro | ||
| 169 | |.macro checktab, reg, target; checktp reg, LJ_TTAB; bne target; .endmacro | ||
| 170 | |.macro checkfunc, reg, target; checktp reg, LJ_TFUNC; bne target; .endmacro | ||
| 171 | | | ||
| 166 | |// Assumes DISPATCH is relative to GL. | 172 | |// Assumes DISPATCH is relative to GL. |
| 167 | #define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field)) | 173 | #define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field)) |
| 168 | #define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field)) | 174 | #define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field)) |
| @@ -177,6 +183,10 @@ | |||
| 177 | | NYI | 183 | | NYI |
| 178 | |.endmacro | 184 | |.endmacro |
| 179 | | | 185 | | |
| 186 | |// Set current VM state. | ||
| 187 | |.macro mv_vmstate, reg, st; mvn reg, #LJ_VMST_..st; .endmacro | ||
| 188 | |.macro st_vmstate, reg; str reg, [DISPATCH, #DISPATCH_GL(vmstate)]; .endmacro | ||
| 189 | | | ||
| 180 | |//----------------------------------------------------------------------- | 190 | |//----------------------------------------------------------------------- |
| 181 | 191 | ||
| 182 | /* Generate subroutines used by opcodes and other parts of the VM. */ | 192 | /* Generate subroutines used by opcodes and other parts of the VM. */ |
| @@ -190,19 +200,88 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 190 | |//----------------------------------------------------------------------- | 200 | |//----------------------------------------------------------------------- |
| 191 | | | 201 | | |
| 192 | |->vm_returnp: | 202 | |->vm_returnp: |
| 193 | | NYI | 203 | | // See vm_return. Also: RB = previous base. |
| 204 | | tst PC, #FRAME_P | ||
| 205 | | beq ->cont_dispatch | ||
| 206 | | | ||
| 207 | | // Return from pcall or xpcall fast func. | ||
| 208 | | ldr PC, [RB, FRAME_PC] // Fetch PC of previous frame. | ||
| 209 | | mvn CARG2, #~LJ_TTRUE | ||
| 210 | | mov BASE, RB | ||
| 211 | | // Prepending may overwrite the pcall frame, so do it at the end. | ||
| 212 | | str CARG2, [RA, FRAME_PC] // Prepend true to results. | ||
| 213 | | sub RA, RA, #8 | ||
| 194 | | | 214 | | |
| 195 | |->vm_returnc: | 215 | |->vm_returnc: |
| 196 | | NYI | 216 | | add RC, RC, #8 // RC = (nresults+1)*8. |
| 217 | | ands CARG1, PC, #FRAME_TYPE | ||
| 218 | | str RC, SAVE_MULTRES | ||
| 219 | | beq ->BC_RET_Z // Handle regular return to Lua. | ||
| 197 | | | 220 | | |
| 198 | |->vm_return: | 221 | |->vm_return: |
| 199 | | NYI | 222 | | // BASE = base, RA = resultptr, RC/MULTRES = (nresults+1)*8, PC = return |
| 223 | | // CARG1 = PC & FRAME_TYPE | ||
| 224 | | bic RB, PC, #FRAME_TYPEP | ||
| 225 | | cmp CARG1, #FRAME_C | ||
| 226 | | sub RB, BASE, RB // RB = previous base. | ||
| 227 | | bne ->vm_returnp | ||
| 228 | | | ||
| 229 | | str RB, L->base | ||
| 230 | | ldr KBASE, SAVE_NRES | ||
| 231 | | mv_vmstate CARG4, C | ||
| 232 | | sub BASE, BASE, #8 | ||
| 233 | | subs CARG3, RC, #8 | ||
| 234 | | lsl KBASE, KBASE, #3 // KBASE = (nresults_wanted+1)*8 | ||
| 235 | | st_vmstate CARG4 | ||
| 236 | | beq >2 | ||
| 237 | |1: | ||
| 238 | | subs CARG3, CARG3, #8 | ||
| 239 | | ldrd CARG12, [RA], #8 | ||
| 240 | | strd CARG12, [BASE], #8 | ||
| 241 | | bne <1 | ||
| 242 | |2: | ||
| 243 | | cmp KBASE, RC // More/less results wanted? | ||
| 244 | | bne >6 | ||
| 245 | |3: | ||
| 246 | | str BASE, L->top // Store new top. | ||
| 200 | | | 247 | | |
| 201 | |->vm_leave_cp: | 248 | |->vm_leave_cp: |
| 202 | | NYI | 249 | | ldr RC, SAVE_CFRAME // Restore previous C frame. |
| 250 | | mov CRET1, #0 // Ok return status for vm_pcall. | ||
| 251 | | str RC, L->cframe | ||
| 203 | | | 252 | | |
| 204 | |->vm_leave_unw: | 253 | |->vm_leave_unw: |
| 205 | | NYI | 254 | | restoreregs_ret |
| 255 | | | ||
| 256 | |6: | ||
| 257 | | blt >7 // Less results wanted? | ||
| 258 | | // More results wanted. Check stack size and fill up results with nil. | ||
| 259 | | ldr CARG3, L->maxstack | ||
| 260 | | mvn CARG2, #~LJ_TNIL | ||
| 261 | | cmp BASE, CARG3 | ||
| 262 | | bhs >8 | ||
| 263 | | str CARG2, [BASE, #4] | ||
| 264 | | add RC, RC, #8 | ||
| 265 | | add BASE, BASE, #8 | ||
| 266 | | b <2 | ||
| 267 | | | ||
| 268 | |7: // Less results wanted. | ||
| 269 | | sub CARG1, RC, KBASE | ||
| 270 | | cmp KBASE, #0 // LUA_MULTRET+1 case? | ||
| 271 | | subne BASE, BASE, CARG1 // Either keep top or shrink it. | ||
| 272 | | b <3 | ||
| 273 | | | ||
| 274 | |8: // Corner case: need to grow stack for filling up results. | ||
| 275 | | // This can happen if: | ||
| 276 | | // - A C function grows the stack (a lot). | ||
| 277 | | // - The GC shrinks the stack in between. | ||
| 278 | | // - A return back from a lua_call() with (high) nresults adjustment. | ||
| 279 | | str BASE, L->top // Save current top held in BASE (yes). | ||
| 280 | | mov CARG2, KBASE | ||
| 281 | | mov CARG1, L | ||
| 282 | | bl extern lj_state_growstack // (lua_State *L, int n) | ||
| 283 | | ldr BASE, L->top // Need the (realloced) L->top in BASE. | ||
| 284 | | b <2 | ||
| 206 | | | 285 | | |
| 207 | |->vm_unwind_c: // Unwind C stack, return from vm_pcall. | 286 | |->vm_unwind_c: // Unwind C stack, return from vm_pcall. |
| 208 | | NYI | 287 | | NYI |
| @@ -232,19 +311,71 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 232 | | NYI | 311 | | NYI |
| 233 | | | 312 | | |
| 234 | |->vm_pcall: // Setup protected C frame and enter VM. | 313 | |->vm_pcall: // Setup protected C frame and enter VM. |
| 235 | | NYI | 314 | | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef) |
| 315 | | saveregs | ||
| 316 | | mov PC, #FRAME_CP | ||
| 317 | | str CARG4, SAVE_ERRF | ||
| 318 | | b >1 | ||
| 236 | | | 319 | | |
| 237 | |->vm_call: // Setup C frame and enter VM. | 320 | |->vm_call: // Setup C frame and enter VM. |
| 238 | | NYI | 321 | | // (lua_State *L, TValue *base, int nres1) |
| 322 | | saveregs | ||
| 323 | | mov PC, #FRAME_C | ||
| 324 | | | ||
| 325 | |1: // Entry point for vm_pcall above (PC = ftype). | ||
| 326 | | ldr RC, L:CARG1->cframe | ||
| 327 | | str CARG3, SAVE_NRES | ||
| 328 | | mov L, CARG1 | ||
| 329 | | str CARG1, SAVE_L | ||
| 330 | | mov BASE, CARG2 | ||
| 331 | | str sp, L->cframe // Add our C frame to cframe chain. | ||
| 332 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. | ||
| 333 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. | ||
| 334 | | str RC, SAVE_CFRAME | ||
| 335 | | add DISPATCH, DISPATCH, #GG_G2DISP | ||
| 336 | | | ||
| 337 | |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). | ||
| 338 | | ldr RB, L->base // RB = old base (for vmeta_call). | ||
| 339 | | ldr CARG1, L->top | ||
| 340 | | mov MASKR8, #255 | ||
| 341 | | add PC, PC, BASE | ||
| 342 | | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8. | ||
| 343 | | sub PC, PC, RB // PC = frame delta + frame type | ||
| 344 | | mv_vmstate CARG2, INTERP | ||
| 345 | | sub NARGS8:RC, CARG1, BASE | ||
| 346 | | st_vmstate CARG2 | ||
| 239 | | | 347 | | |
| 240 | |->vm_call_dispatch: | 348 | |->vm_call_dispatch: |
| 241 | | NYI | 349 | | // RB = old base, BASE = new base, RC = nargs*8, PC = caller PC |
| 350 | | ldrd CARG34, [BASE, FRAME_FUNC] | ||
| 351 | | checkfunc CARG4, ->vmeta_call | ||
| 242 | | | 352 | | |
| 243 | |->vm_call_dispatch_f: | 353 | |->vm_call_dispatch_f: |
| 244 | | NYI | 354 | | ins_call |
| 355 | | // BASE = new base, RC = nargs*8 | ||
| 245 | | | 356 | | |
| 246 | |->vm_cpcall: // Setup protected C frame, call C. | 357 | |->vm_cpcall: // Setup protected C frame, call C. |
| 247 | | NYI | 358 | | // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp) |
| 359 | | saveregs | ||
| 360 | | mov L, CARG1 | ||
| 361 | | ldr RA, L:CARG1->stack | ||
| 362 | | str CARG1, SAVE_L | ||
| 363 | | ldr RB, L->top | ||
| 364 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. | ||
| 365 | | ldr RC, L->cframe | ||
| 366 | | sub RA, RA, RB // Compute -savestack(L, L->top). | ||
| 367 | | str sp, L->cframe // Add our C frame to cframe chain. | ||
| 368 | | mov RB, #0 | ||
| 369 | | str RA, SAVE_NRES // Neg. delta means cframe w/o frame. | ||
| 370 | | str RB, SAVE_ERRF // No error function. | ||
| 371 | | str RC, SAVE_CFRAME | ||
| 372 | | blx CARG4 // (lua_State *L, lua_CFunction func, void *ud) | ||
| 373 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. | ||
| 374 | | movs BASE, CRET1 | ||
| 375 | | mov PC, #FRAME_CP | ||
| 376 | | add DISPATCH, DISPATCH, #GG_G2DISP | ||
| 377 | | bne <3 // Else continue with the call. | ||
| 378 | | b ->vm_leave_cp // No base? Just remove C frame. | ||
| 248 | | | 379 | | |
| 249 | |//----------------------------------------------------------------------- | 380 | |//----------------------------------------------------------------------- |
| 250 | |//-- Metamethod handling ------------------------------------------------ | 381 | |//-- Metamethod handling ------------------------------------------------ |
