riscv(interp): strip excessive extended branch (^B+J)

This commit is contained in:
gns 2025-01-16 01:02:19 +08:00
parent bedd0cf1e1
commit fd1422f59e

View File

@ -553,7 +553,7 @@ static void build_subroutines(BuildCtx *ctx)
|
| // Return from pcall or xpcall fast func.
| mov_true TMP1
| bxeqz TMP0, ->cont_dispatch
| beqz TMP0, ->cont_dispatch
| ld PC, FRAME_PC(TMP2) // Fetch PC of previous frame.
| mv BASE, TMP2 // Restore caller base.
| // Prepending may overwrite the pcall frame, so do it at the end.
@ -564,9 +564,9 @@ static void build_subroutines(BuildCtx *ctx)
| addiw RD, RD, 8 // RD = (nresults+1)*8.
| andi TMP0, PC, FRAME_TYPE
| li CRET1, LUA_YIELD
| bxeqz RD, ->vm_unwind_c_eh
| beqz RD, ->vm_unwind_c_eh
| mv MULTRES, RD
| bxeqz TMP0, ->BC_RET_Z // Handle regular return to Lua.
| beqz TMP0, ->BC_RET_Z // Handle regular return to Lua.
|
|->vm_return:
| // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return
@ -574,7 +574,7 @@ static void build_subroutines(BuildCtx *ctx)
| andi TMP2, PC, ~FRAME_TYPEP
| xori TMP0, TMP0, FRAME_C
| sub TMP2, BASE, TMP2 // TMP2 = previous base.
| bxnez TMP0, ->vm_returnp
| bnez TMP0, ->vm_returnp
|
| addiw TMP1, RD, -8
| sd TMP2, L->base
@ -743,7 +743,7 @@ static void build_subroutines(BuildCtx *ctx)
| andi TMP0, PC, FRAME_TYPE
| li TISNIL, LJ_TNIL
| li TISNUM, LJ_TISNUM
| bxeqz TMP0, ->BC_RET_Z
| beqz TMP0, ->BC_RET_Z
| j ->vm_return
|
|->vm_pcall: // Setup protected C frame and enter VM.
@ -1003,7 +1003,7 @@ static void build_subroutines(BuildCtx *ctx)
| // Returns 0/1 or TValue * (metamethod).
|3:
| sltiu TMP1, CRET1, 2
| bxeqz TMP1, ->vmeta_binop
| beqz TMP1, ->vmeta_binop
| negw TMP2, CRET1
|4:
| lhu RD, OFS_RD(PC)
@ -1091,7 +1091,7 @@ static void build_subroutines(BuildCtx *ctx)
| // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
| call_intern vmeta_arith, lj_meta_arith
| // Returns NULL (finished) or TValue * (metamethod).
| bxeqz CRET1, ->cont_nop
| beqz CRET1, ->cont_nop
|
| // Call metamethod for binary op.
|->vmeta_binop:
@ -1115,7 +1115,7 @@ static void build_subroutines(BuildCtx *ctx)
| call_intern vmeta_len, lj_meta_len // (lua_State *L, TValue *o)
| // Returns NULL (retry) or TValue * (metamethod base).
#if LJ_52
| bxnez CRET1, ->vmeta_binop // Binop call for compatibility.
| bnez CRET1, ->vmeta_binop // Binop call for compatibility.
| mv CARG1, MULTRES
| j ->BC_LEN_Z
#else
@ -1201,7 +1201,7 @@ static void build_subroutines(BuildCtx *ctx)
|->ff_ .. name:
| ld CARG1, 0(BASE)
| fld FARG1, 0(BASE)
| bxeqz NARGS8:RC, ->fff_fallback
| beqz NARGS8:RC, ->fff_fallback
| checknum CARG1, ->fff_fallback
|.endmacro
|
@ -1210,7 +1210,7 @@ static void build_subroutines(BuildCtx *ctx)
| ld CARG1, 0(BASE)
| sltiu TMP0, NARGS8:RC, 16
| ld CARG2, 8(BASE)
| bxnez TMP0, ->fff_fallback
| bnez TMP0, ->fff_fallback
| gettp TMP1, CARG1
| gettp TMP2, CARG2
| sltiu TMP1, TMP1, LJ_TISNUM
@ -1218,7 +1218,7 @@ static void build_subroutines(BuildCtx *ctx)
| fld FARG1, 0(BASE)
| and TMP1, TMP1, TMP2
| fld FARG2, 8(BASE)
| bxeqz TMP1, ->fff_fallback
| beqz TMP1, ->fff_fallback
|.endmacro
|
|// Inlined GC threshold check.
@ -1278,7 +1278,7 @@ static void build_subroutines(BuildCtx *ctx)
|2:
| ld STR:RC, GL->gcroot[GCROOT_MMNAME+MM_metatable]
| li CARG1, LJ_TNIL
| bxeqz TAB:RB, ->fff_restv
| beqz TAB:RB, ->fff_restv
| lw TMP0, TAB:RB->hmask
| lw TMP1, STR:RC->sid
| ld NODE:TMP2, TAB:RB->node
@ -1300,7 +1300,7 @@ static void build_subroutines(BuildCtx *ctx)
| settp CARG1, RB, TMP3
| j ->fff_restv // Not found, keep default result.
|5:
| bxne CARG1, TISNIL, ->fff_restv
| bne CARG1, TISNIL, ->fff_restv
| j <4 // Ditto for nil value.
|
|6:
@ -1326,7 +1326,7 @@ static void build_subroutines(BuildCtx *ctx)
| bxnez TMP3, ->fff_fallback
| andi TMP3, TMP2, LJ_GC_BLACK // isblack(table)
| sd TAB:CARG2, TAB:TMP1->metatable
| bxeqz TMP3, ->fff_restv
| beqz TMP3, ->fff_restv
| barrierback TAB:TMP1, TMP2, TMP0, ->fff_restv
|
|.ffunc rawget
@ -1361,7 +1361,7 @@ static void build_subroutines(BuildCtx *ctx)
| gettp TMP0, CARG1
| addi TMP1, TMP0, -LJ_TSTR
| // A __tostring method in the string base metatable is ignored.
| bxeqz TMP1, ->fff_restv // String key?
| beqz TMP1, ->fff_restv // String key?
| // Handle numbers inline, unless a number base metatable is present.
| ld TMP1, GL->gcroot[GCROOT_BASEMT_NUM]
| sltu TMP0, TISNUM, TMP0
@ -1391,10 +1391,10 @@ static void build_subroutines(BuildCtx *ctx)
| call_intern ff_next, lj_tab_next // (GCtab *t, cTValue *key, TValue *o)
| // Returns 1=found, 0=end, -1=error.
| li RD, (2+1)*8
| bxgtz CRET1, ->fff_res // Found key/value.
| bgtz CRET1, ->fff_res // Found key/value.
| mv TMP1, CRET1
| mv CARG1, TISNIL
| bxeqz TMP1, ->fff_restv // End of traversal: return nil.
| beqz TMP1, ->fff_restv // End of traversal: return nil.
| ld CFUNC:RB, FRAME_FUNC(BASE)
| li RC, 2*8
| cleartp CFUNC:RB
@ -1434,19 +1434,19 @@ static void build_subroutines(BuildCtx *ctx)
| ld TMP1, 0(TMP3)
|1:
| li RD, (0+1)*8
| bxeq TMP1, TISNIL, ->fff_res // End of iteration, return 0 results.
| beq TMP1, TISNIL, ->fff_res // End of iteration, return 0 results.
| sd TMP1, -8(BASE)
| li RD, (2+1)*8
| j ->fff_res
|2: // Check for empty hash part first. Otherwise call C function.
| lw TMP0, TAB:CARG1->hmask
| li RD, (0+1)*8
| bxeqz TMP0, ->fff_res
| beqz TMP0, ->fff_res
| mv CARG2, TMP2
| call_intern ff_ipairs_aux, lj_tab_getinth // (GCtab *t, int32_t key)
| // Returns cTValue * or NULL.
| li RD, (0+1)*8
| bxeqz CRET1, ->fff_res
| beqz CRET1, ->fff_res
| ld TMP1, 0(CRET1)
| j <1
|
@ -1483,7 +1483,7 @@ static void build_subroutines(BuildCtx *ctx)
| srliw TMP3, TMP3, HOOK_ACTIVE_SHIFT
| andi TMP3, TMP3, 1
| addi PC, TMP3, 16+FRAME_PCALL
| bxeqz NARGS8:RC, ->vm_call_dispatch
| beqz NARGS8:RC, ->vm_call_dispatch
|1:
| add TMP0, BASE, NARGS8:RC
|2:
@ -1540,17 +1540,17 @@ static void build_subroutines(BuildCtx *ctx)
| xor CARG2, CARG2, TMP3 // CARG2 = TMP4 ? CARG2 : TMP3
| and CARG2, CARG2, TMP4
| xor CARG2, TMP3, CARG2
| bxgtz CARG4, ->fff_fallback // st > LUA_YIELD?
| bgtz CARG4, ->fff_fallback // st > LUA_YIELD?
| xor TMP2, TMP2, CARG3
| or CARG4, TMP2, TMP0
| bxnez TMP1, ->fff_fallback // cframe != 0?
| bnez TMP1, ->fff_fallback // cframe != 0?
| ld TMP0, L:CARG1->maxstack
| ld PC, FRAME_PC(BASE)
| bxeqz CARG4, ->fff_fallback // base == top && st == 0?
| beqz CARG4, ->fff_fallback // base == top && st == 0?
| add TMP2, CARG2, NARGS8:RC
| sd BASE, L->base
| sd PC, SAVE_PC(sp)
| bxltu TMP0, TMP2, ->fff_fallback // Stack overflow?
| bltu TMP0, TMP2, ->fff_fallback // Stack overflow?
|1:
|.if resume
| addi BASE, BASE, 8 // Keep resumed thread in stack for GC.
@ -1655,7 +1655,7 @@ static void build_subroutines(BuildCtx *ctx)
| sd BASE, L->base
| andi TMP0, TMP0, CFRAME_RESUME
| sd TMP1, L->top
| bxeqz TMP0, ->fff_fallback
| beqz TMP0, ->fff_fallback
| sd x0, L->cframe
| sb CRET1, L->status
| j ->vm_leave_unw
@ -1666,14 +1666,14 @@ static void build_subroutines(BuildCtx *ctx)
|->ff_math_ .. func:
| ld CARG1, 0(BASE)
| gettp TMP0, CARG1
| bxeqz NARGS8:RC, ->fff_fallback
| beqz NARGS8:RC, ->fff_fallback
| fmv.d.x FARG1, CARG1
| bxeq TMP0, TISNUM, ->fff_restv
| beq TMP0, TISNUM, ->fff_restv
| srli TMP1, CARG1, 52 // Extract exponent (and sign).
| bxgeu TMP0, TISNUM, ->fff_fallback
| bgeu TMP0, TISNUM, ->fff_fallback
| andi TMP1, TMP1, 0x7ff // Extract exponent.
| slti TMP2, TMP1, 1023 + 52 + 1 // 1023: Bias, 52: Max fraction
| bxeqz TMP2, ->fff_resn // Less than 2^52 / Not NaN?
| beqz TMP2, ->fff_resn // Less than 2^52 / Not NaN?
| fcvt.l.d TMP3, FARG1, rm
| fcvt.d.l FTMP1, TMP3
| fsgnj.d FRET1, FTMP1, FARG1
@ -1693,7 +1693,7 @@ static void build_subroutines(BuildCtx *ctx)
| sub CARG1, TMP1, TMP0
| slli TMP3, CARG1, 32
| settp CARG1, TISNUM
| bxgez TMP3, ->fff_restv
| bgez TMP3, ->fff_restv
| lui CARG1, 0x41e00 // 2^31 as a double.
| slli CARG1, CARG1, 32
| j ->fff_restv
@ -1701,7 +1701,7 @@ static void build_subroutines(BuildCtx *ctx)
| sltiu TMP2, CARG2, LJ_TISNUM
| slli CARG1, CARG1, 1
| srli CARG1, CARG1, 1
| bxeqz TMP2, ->fff_fallback // int
| beqz TMP2, ->fff_fallback // int
|// fallthrough
|
|->fff_restv:
@ -1757,7 +1757,7 @@ static void build_subroutines(BuildCtx *ctx)
| li TMP1, 8
| ld CARG1, 0(BASE)
| fld FARG1, 0(BASE)
| bxne NARGS8:RC, TMP1, ->fff_fallback // Need exactly 1 argument.
| bne NARGS8:RC, TMP1, ->fff_fallback // Need exactly 1 argument.
| checknum CARG1, ->fff_fallback
| call_extern ff_math_log, log
| j ->fff_resn
@ -1811,7 +1811,7 @@ static void build_subroutines(BuildCtx *ctx)
| checkint CARG1, >4
|1: // Handle integers.
| ld CARG2, 0(RA)
| bxeq RA, RB, ->fff_restv
| beq RA, RB, ->fff_restv
| sext.w CARG1, CARG1
| checkint CARG2, >3
| sext.w CARG2, CARG2
@ -1840,7 +1840,7 @@ static void build_subroutines(BuildCtx *ctx)
|5: // Handle numbers.
| ld CARG2, 0(RA)
| fld FARG2, 0(RA)
| bxgeu RA, RB, ->fff_resn
| bgeu RA, RB, ->fff_resn
| checknum CARG2, >7
|6:
|.if ismax
@ -1871,7 +1871,7 @@ static void build_subroutines(BuildCtx *ctx)
| addi TMP0, TMP0, -LJ_TSTR
| or TMP1, TMP1, TMP0
| cleartp STR:CARG1
| bxnez TMP1, ->fff_fallback // Need exactly 1 string argument.
| bnez TMP1, ->fff_fallback // Need exactly 1 string argument.
| lw TMP0, STR:CARG1->len
| ld PC, FRAME_PC(BASE)
| snez RD, TMP0
@ -1894,7 +1894,7 @@ static void build_subroutines(BuildCtx *ctx)
| sltu TMP2, TMP2, CARG1 // !(255 < n).
| or TMP1, TMP1, TMP2
| li CARG3, 1
| bxnez TMP1, ->fff_fallback
| bnez TMP1, ->fff_fallback
| addi CARG2, sp, TMPD_OFS
| sb CARG1, TMPD(sp)
|->fff_newstr:
@ -1917,7 +1917,7 @@ static void build_subroutines(BuildCtx *ctx)
| ld CARG3, 16(BASE)
| addi TMP0, NARGS8:RC, -16
| gettp TMP1, CARG1
| bxltz TMP0, ->fff_fallback
| bltz TMP0, ->fff_fallback
| cleartp STR:CARG1, CARG1
| li CARG4, -1
| beqz TMP0, >1
@ -1927,7 +1927,7 @@ static void build_subroutines(BuildCtx *ctx)
| checkint CARG2, ->fff_fallback
| addi TMP0, TMP1, -LJ_TSTR
| sext.w CARG3, CARG2
| bxnez TMP0, ->fff_fallback
| bnez TMP0, ->fff_fallback
| lw CARG2, STR:CARG1->len
| // STR:CARG1 = str, CARG2 = str->len, CARG3 = start, CARG4 = end
| addiw TMP0, CARG2, 1
@ -1950,7 +1950,7 @@ static void build_subroutines(BuildCtx *ctx)
| sub CARG3, CARG4, CARG3 // len = end - start
| addi CARG2, CARG2, sizeof(GCstr)-1
| addiw CARG3, CARG3, 1 // len += 1
| bxgez CARG3, ->fff_newstr
| bgez CARG3, ->fff_newstr
|->fff_emptystr: // Return empty string.
| li TMP1, LJ_TSTR
| addi STR:CARG1, GL, offsetof(global_State, strempty)
@ -1961,7 +1961,7 @@ static void build_subroutines(BuildCtx *ctx)
| .ffunc string_ .. name
| ffgccheck
| ld CARG2, 0(BASE)
| bxeqz NARGS8:RC, ->fff_fallback
| beqz NARGS8:RC, ->fff_fallback
| checkstr STR:CARG2, ->fff_fallback
| addi SBUF:CARG1, GL, offsetof(global_State, tmpbuf)
| ld TMP0, SBUF:CARG1->b
@ -1983,7 +1983,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|->vm_tobit_fb:
| fld FARG1, 0(BASE)
| bxeqz TMP1, ->fff_fallback
| beqz TMP1, ->fff_fallback
| fadd.d FARG1, FARG1, TOBIT
| fmv.x.w CRET1, FARG1
| zext.w CRET1, CRET1
@ -2005,7 +2005,7 @@ static void build_subroutines(BuildCtx *ctx)
| add TMP3, BASE, NARGS8:RC
|1:
| ld TMP1, 0(TMP2)
| bxeq TMP2, TMP3, ->fff_resi
| beq TMP2, TMP3, ->fff_resi
| gettp TMP0, TMP1
| addi TMP2, TMP2, 8
| bne TMP0, TISNUM, >2
@ -2016,7 +2016,7 @@ static void build_subroutines(BuildCtx *ctx)
| fld FARG1, -8(TMP2)
| sltiu TMP0, TMP0, LJ_TISNUM
| fadd.d FARG1, FARG1, TOBIT
| bxeqz TMP0, ->fff_fallback
| beqz TMP0, ->fff_fallback
| fmv.x.w TMP1, FARG1
| zext.w TMP1, TMP1
| bins CRET1, CRET1, TMP1
@ -2064,7 +2064,7 @@ static void build_subroutines(BuildCtx *ctx)
|1:
| gettp TMP0, CARG2
| zext.w CARG2, CARG2
| bxne TMP0, TISNUM, ->fff_fallback
| bne TMP0, TISNUM, ->fff_fallback
| sext.w CARG1, CARG1
| shins CRET1, CARG1, CARG2
| zext.w CRET1, CRET1
@ -2085,7 +2085,7 @@ static void build_subroutines(BuildCtx *ctx)
|1:
| gettp TMP0, CARG2
| zext.w CARG2, CARG2
| bxne TMP0, TISNUM, ->fff_fallback
| bne TMP0, TISNUM, ->fff_fallback
| sext.w CARG1, CARG1
| neg TMP2, CARG2
| rotinsa TMP1, CARG1, CARG2
@ -2116,13 +2116,13 @@ static void build_subroutines(BuildCtx *ctx)
| // Either throws an error, or recovers and returns -1, 0 or nresults+1.
| ld BASE, L->base
| slliw RD, CRET1, 3
| bxgtz CRET1, ->fff_res // Returned nresults+1?
| bgtz CRET1, ->fff_res // Returned nresults+1?
|1: // Returned 0 or -1: retry fast path.
| ld LFUNC:RB, FRAME_FUNC(BASE)
| ld TMP0, L->top
| sub NARGS8:RC, TMP0, BASE
| cleartp LFUNC:RB
| bxnez CRET1, ->vm_call_tail // Returned -1?
| bnez CRET1, ->vm_call_tail // Returned -1?
| ins_callt // Returned 0: retry fast path.
|
|// Reconstruct previous base for vmeta_call during tailcall.
@ -4297,7 +4297,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|->BC_RETV_Z: // Non-standard return case.
| andi TMP2, TMP1, FRAME_TYPEP
| bxnez TMP2, ->vm_return
| bnez TMP2, ->vm_return
| // Return from vararg function: relocate BASE down.
| sub BASE, BASE, TMP1
| ld PC, FRAME_PC(BASE)
@ -4550,7 +4550,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| ld TMP2, L->maxstack
| lbu TMP1, -4+PC2PROTO(numparams)(PC)
| ld KBASE, -4+PC2PROTO(k)(PC)
| bxltu TMP2, RA, ->vm_growstack_l
| bltu TMP2, RA, ->vm_growstack_l
| slliw TMP1, TMP1, 3 // numparams*8
|2:
| bltu NARGS8:RC, TMP1, >3 // Check for missing parameters.
@ -4587,7 +4587,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| addi TMP3, RC, 16+FRAME_VARG
| ld KBASE, -4+PC2PROTO(k)(PC)
| sd TMP3, 8(TMP1) // Store delta + FRAME_VARG.
| bxgeu TMP0, TMP2, ->vm_growstack_l
| bgeu TMP0, TMP2, ->vm_growstack_l
| lbu TMP2, -4+PC2PROTO(numparams)(PC)
| mv RA, BASE
| mv RC, TMP1
@ -4633,7 +4633,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| add RC, BASE, NARGS8:RC
| sd BASE, L->base // base of currently excuting function
| sd RC, L->top
| bxgtu TMP1, TMP2, ->vm_growstack_c // Need to grow stack.
| bgtu TMP1, TMP2, ->vm_growstack_c // Need to grow stack.
| li_vmstate C // li TMP0, ~LJ_VMST_C
if (op == BC_FUNCCW) {
| ld CARG2, CFUNC:RB->f