Pārlūkot izejas kodu

ARM: Add tailcall instructions.

Mike Pall 14 gadi atpakaļ
vecāks
revīzija
aee129a789
1 mainītis faili ar 53 papildinājumiem un 2 dzēšanām
  1. 53 2
      src/buildvm_arm.dasc

+ 53 - 2
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: