From 711e55bdf8b2481750b33cdbd9bc154830b6e4e8 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Sat, 4 Sep 2010 12:58:36 +0200 Subject: [PATCH] PPC: Add tailcall instructions. --- src/buildvm_ppc.dasc | 57 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/buildvm_ppc.dasc b/src/buildvm_ppc.dasc index 3947cc30..76d54f42 100644 --- a/src/buildvm_ppc.dasc +++ b/src/buildvm_ppc.dasc @@ -579,6 +579,9 @@ static void build_subroutines(BuildCtx *ctx) |->vmeta_call: // Resolve and call __call metamethod. | NYI | + |->vmeta_callt: // Resolve __call for BC_CALLT. + | NYI + | |//-- Argument coercion for 'for' statement ------------------------------ | |->vmeta_for: @@ -1538,10 +1541,60 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) break; case BC_CALLMT: - | NYI + | // RA = base*8, (RB = 0,) RC = extra_nargs*8 + | lwz TMP0, SAVE_MULTRES + | add NARGS8:RC, NARGS8:RC, TMP0 + | // Fall through. Assumes BC_CALLT follows. break; case BC_CALLT: - | NYI + | // RA = base*8, (RB = 0,) RC = (nargs+1)*8 + | evlddx LFUNC:RB, BASE, RA + | add RA, BASE, RA + | lwz TMP1, FRAME_PC(BASE) + | subi NARGS8:RC, NARGS8:RC, 8 + | checkfunc LFUNC:RB + | addi RA, RA, 8 + | checkfail ->vmeta_callt + |->BC_CALLT_Z: + | andi. TMP0, TMP1, FRAME_TYPE // Caveat: preserve cr0 until the crand. + | lbz TMP3, LFUNC:RB->ffid + | xori TMP2, TMP1, FRAME_VARG + | cmpwi cr1, NARGS8:RC, 0 + | bne >7 + |1: + | stw LFUNC:RB, FRAME_FUNC(BASE) // Copy function down, but keep PC. + | li TMP2, 0 + | cmplwi cr7, TMP3, 1 // (> FF_C) Calling a fast function? + | beq cr1, >3 + |2: + | addi TMP3, TMP2, 8 + | evlddx TMP0, RA, TMP2 + | cmpw cr1, TMP3, NARGS8:RC + | evstddx TMP0, BASE, TMP2 + | mr TMP2, TMP3 + | bne cr1, <2 + |3: + | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+gt + | beq >5 + |4: + | ins_callt + | + |5: // Tailcall to a fast function with a Lua frame below. + | lwz INS, -4(TMP1) + | decode_RA8 RA, INS + | sub TMP1, BASE, RA + | lwz LFUNC:TMP1, FRAME_FUNC(TMP1) + | lwz TMP1, LFUNC:TMP1->pc + | lwz KBASE, PC2PROTO(k)(TMP1) // Need to prepare KBASE. + | b <4 + | + |7: // Tailcall from a vararg function. + | andi. TMP0, TMP2, FRAME_TYPEP + | bne <1 // Vararg frame below? + | sub BASE, BASE, TMP2 // Relocate BASE down. + | lwz TMP1, FRAME_PC(BASE) + | andi. TMP0, TMP1, FRAME_TYPE + | b <1 break; case BC_ITERC: