PPC: Add tailcall instructions.

This commit is contained in:
Mike Pall 2010-09-04 12:58:36 +02:00
parent 684acbe930
commit 711e55bdf8

View File

@ -579,6 +579,9 @@ static void build_subroutines(BuildCtx *ctx)
|->vmeta_call: // Resolve and call __call metamethod. |->vmeta_call: // Resolve and call __call metamethod.
| NYI | NYI
| |
|->vmeta_callt: // Resolve __call for BC_CALLT.
| NYI
|
|//-- Argument coercion for 'for' statement ------------------------------ |//-- Argument coercion for 'for' statement ------------------------------
| |
|->vmeta_for: |->vmeta_for:
@ -1538,10 +1541,60 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
break; break;
case BC_CALLMT: 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; break;
case BC_CALLT: 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; break;
case BC_ITERC: case BC_ITERC: