diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index 14a60fd3..f24d8190 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc @@ -2334,10 +2334,61 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) break; case BC_CALLMT: - | NYI + | // RA = base*8, (RB = 0,) RC = extra_nargs + | ldr CARG1, SAVE_MULTRES + | add NARGS8:RC, CARG1, RC, lsl #3 + | b ->BC_CALLT1_Z break; case BC_CALLT: - | NYI + | lsl NARGS8:RC, RC, #3 + | // RA = base*8, (RB = 0,) RC = (nargs+1)*8 + |->BC_CALLT1_Z: + | ldrd LFUNC:CARG34, [RA, BASE]! + | sub NARGS8:RC, NARGS8:RC, #8 + | add RA, RA, #8 + | checkfunc CARG4, ->vmeta_callt + | ldr PC, [BASE, FRAME_PC] + |->BC_CALLT2_Z: + | str LFUNC:CARG3, [BASE, FRAME_FUNC] // Copy function down, but keep PC. + | ldrb CARG4, LFUNC:CARG3->ffid + | tst PC, #FRAME_TYPE + | bne >7 + |1: + | cmp NARGS8:RC, #0 + | mov RB, #0 + | beq >3 + |2: + | ldrd CARG12, [RA, RB] + | add INS, RB, #8 + | cmp INS, NARGS8:RC + | strd CARG12, [BASE, RB] + | mov RB, INS + | bne <2 + |3: + | cmp CARG4, #1 // (> FF_C) Calling a fast function? + | bhi >5 + |4: + | ins_callt + | + |5: // Tailcall to a fast function with a Lua frame below. + | ldr INS, [PC, #-4] + | decode_RA8 RA, INS + | sub CARG1, BASE, RA + | ldr LFUNC:CARG1, [CARG1, #-16] + | ldr CARG1, LFUNC:CARG1->field_pc + | ldr KBASE, [CARG1, #PC2PROTO(k)] + | b <4 + | + |7: // Tailcall from a vararg function. + | eor PC, PC, #FRAME_VARG + | tst PC, #FRAME_TYPEP // Vararg frame below? + | movne CARG4, #0 // Clear ffid if no Lua function below. + | bne <1 + | sub BASE, BASE, PC + | ldr PC, [BASE, FRAME_PC] + | tst PC, #FRAME_TYPE + | movne CARG4, #0 // Clear ffid if no Lua function below. + | b <1 break; case BC_ITERC: