ARM: Add string.* fast functions and GC steps.

This commit is contained in:
Mike Pall 2011-04-10 16:59:38 +02:00
parent da1ef8c3b0
commit 040c8c5737

View File

@ -777,8 +777,12 @@ static void build_subroutines(BuildCtx *ctx)
| bhs ->fff_fallback | bhs ->fff_fallback
|.endmacro |.endmacro
| |
|// Inlined GC threshold check. Caveat: uses CARG1 and CARG2.
|.macro ffgccheck |.macro ffgccheck
| NYI | ldr CARG1, [DISPATCH, #DISPATCH_GL(gc.total)]
| ldr CARG2, [DISPATCH, #DISPATCH_GL(gc.threshold)]
| cmp CARG1, CARG2
| blge ->fff_gcstep
|.endmacro |.endmacro
| |
|//-- Base library: checks ----------------------------------------------- |//-- Base library: checks -----------------------------------------------
@ -897,13 +901,14 @@ static void build_subroutines(BuildCtx *ctx)
| beq ->fff_restv | beq ->fff_restv
| // Handle numbers inline, unless a number base metatable is present. | // Handle numbers inline, unless a number base metatable is present.
| ldr CARG4, [DISPATCH, #DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])] | ldr CARG4, [DISPATCH, #DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])]
| mov CARG1, L | str BASE, L->base
| checktp CARG2, LJ_TISNUM | checktp CARG2, LJ_TISNUM
| cmpls CARG4, #0 | cmpls CARG4, #0
| str PC, SAVE_PC // Redundant (but a defined value).
| bhi ->fff_fallback | bhi ->fff_fallback
| str BASE, L->base | ffgccheck
| mov CARG2, BASE | mov CARG1, L
| str PC, SAVE_PC | mov CARG2, BASE
| bl extern lj_str_fromnumber // (lua_State *L, cTValue *o) | bl extern lj_str_fromnumber // (lua_State *L, cTValue *o)
| // Returns GCstr *. | // Returns GCstr *.
| ldr BASE, L->base | ldr BASE, L->base
@ -1214,26 +1219,156 @@ static void build_subroutines(BuildCtx *ctx)
|//-- String library ----------------------------------------------------- |//-- String library -----------------------------------------------------
| |
|.ffunc_1 string_len |.ffunc_1 string_len
| NYI | checkstr CARG2, ->fff_fallback
| ldr CARG1, STR:CARG1->len
| mvn CARG2, #~LJ_TISNUM
| b ->fff_restv
| |
|.ffunc string_byte // Only handle the 1-arg case here. |.ffunc string_byte // Only handle the 1-arg case here.
| NYI | ldrd CARG12, [BASE]
| ldr PC, [BASE, FRAME_PC]
| cmp NARGS8:RC, #8
| checktpeq CARG2, LJ_TSTR // Need exactly 1 argument.
| bne ->fff_fallback
| ldr CARG3, STR:CARG1->len
| ldrb CARG1, STR:CARG1[1] // Access is always ok (NUL at end).
| mvn CARG2, #~LJ_TISNUM
| cmp CARG3, #0
| moveq RC, #(0+1)*8
| movne RC, #(1+1)*8
| strd CARG12, [BASE, #-8]
| b ->fff_res
| |
|.ffunc string_char // Only handle the 1-arg case here. |.ffunc string_char // Only handle the 1-arg case here.
| NYI | ffgccheck
| ldrd CARG12, [BASE]
| ldr PC, [BASE, FRAME_PC]
| cmp NARGS8:RC, #8 // Need exactly 1 argument.
| checktpeq CARG2, LJ_TISNUM
| bicseq CARG4, CARG1, #255
| mov CARG3, #1
| bne ->fff_fallback
| str CARG1, TMPD
| mov CARG2, TMPDp // Points to stack. Little-endian.
|->fff_newstr:
| // CARG2 = str, CARG3 = len.
| str BASE, L->base
| mov CARG1, L
| str PC, SAVE_PC
| bl extern lj_str_new // (lua_State *L, char *str, size_t l)
| // Returns GCstr *.
| ldr BASE, L->base
| mvn CARG2, #~LJ_TSTR
| b ->fff_restv
| |
|.ffunc string_sub |.ffunc string_sub
| NYI | ffgccheck
| ldrd CARG12, [BASE]
| ldrd CARG34, [BASE, #16]
| cmp NARGS8:RC, #16
| mvn RB, #0
| beq >1
| blo ->fff_fallback
| checktp CARG4, LJ_TISNUM
| mov RB, CARG3
| bne ->fff_fallback
|1:
| ldr CARG34, [BASE, #8]
| checktp CARG2, LJ_TSTR
| ldreq CARG2, STR:CARG1->len
| checktpeq CARG4, LJ_TISNUM
| bne ->fff_fallback
| // CARG1 = str, CARG2 = str->len, CARG3 = start, RB = end
| add CARG4, CARG2, #1
| cmp CARG3, #0 // if (start < 0) start += len+1
| addlt CARG3, CARG3, CARG4
| cmp CARG3, #1 // if (start < 1) start = 1
| movlt CARG3, #1
| cmp RB, #0 // if (end < 0) end += len+1
| addlt RB, RB, CARG4
| bic RB, RB, RB, asr #31 // if (end < 0) end = 0
| cmp RB, CARG2 // if (end > len) end = len
| add CARG1, STR:CARG1, #sizeof(GCstr)-1
| movgt RB, CARG2
| add CARG2, CARG1, CARG3
| subs CARG3, RB, CARG3 // len = start - end
| add CARG3, CARG3, #1 // len += 1
| bge ->fff_newstr
|->fff_emptystr:
| sub STR:CARG1, DISPATCH, #-DISPATCH_GL(strempty)
| mvn CARG2, #~LJ_TSTR
| b ->fff_restv
| |
|.ffunc string_rep // Only handle the 1-char case inline. |.ffunc string_rep // Only handle the 1-char case inline.
| NYI | ffgccheck
| ldrd CARG12, [BASE]
| ldrd CARG34, [BASE, #8]
| cmp NARGS8:RC, #16
| blo ->fff_fallback
| checktp CARG2, LJ_TSTR
| checktpeq CARG4, LJ_TISNUM
| bne ->fff_fallback
| subs CARG4, CARG3, #1
| ldr CARG2, STR:CARG1->len
| blt ->fff_emptystr // Count <= 0?
| cmp CARG2, #1
| blo ->fff_emptystr // Zero-length string?
| bne ->fff_fallback // Fallback for > 1-char strings.
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
| ldr CARG1, STR:CARG1[1]
| cmp RB, CARG3
| blo ->fff_fallback
|1: // Fill buffer with char.
| strb CARG1, [CARG2, CARG4]
| subs CARG4, CARG4, #1
| bge <1
| b ->fff_newstr
| |
|.ffunc string_reverse |.ffunc string_reverse
| NYI | ffgccheck
| ldrd CARG12, [BASE]
| cmp NARGS8:RC, #8
| blo ->fff_fallback
| checkstr CARG2, ->fff_fallback
| ldr CARG3, STR:CARG1->len
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
| mov CARG4, CARG3
| add CARG1, STR:CARG1, #sizeof(GCstr)
| cmp RB, CARG3
| blo ->fff_fallback
|1: // Reverse string copy.
| ldrb RB, [CARG1], #1
| subs CARG4, CARG4, #1
| blt ->fff_newstr
| strb RB, [CARG2, CARG4]
| b <1
| |
|.macro ffstring_case, name, lo |.macro ffstring_case, name, lo
| .ffunc name | .ffunc name
| NYI | ffgccheck
| ldrd CARG12, [BASE]
| cmp NARGS8:RC, #8
| blo ->fff_fallback
| checkstr CARG2, ->fff_fallback
| ldr CARG3, STR:CARG1->len
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)]
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)]
| mov CARG4, #0
| add CARG1, STR:CARG1, #sizeof(GCstr)
| cmp RB, CARG3
| blo ->fff_fallback
|1: // ASCII case conversion.
| ldrb RB, [CARG1, CARG4]
| cmp CARG4, CARG3
| bhs ->fff_newstr
| sub RC, RB, #lo
| cmp RC, #26
| eorlo RB, RB, #0x20
| strb RB, [CARG2, CARG4]
| add CARG4, CARG4, #1
| b <1
|.endmacro |.endmacro
| |
|ffstring_case string_lower, 65 |ffstring_case string_lower, 65
@ -1397,7 +1532,18 @@ static void build_subroutines(BuildCtx *ctx)
| b <1 | b <1
| |
|->fff_gcstep: // Call GC step function. |->fff_gcstep: // Call GC step function.
| NYI | // BASE = new base, RC = nargs*8
| mov RA, lr
| str BASE, L->base
| add CARG2, BASE, NARGS8:RC
| str PC, SAVE_PC // Redundant (but a defined value).
| str CARG2, L->top
| mov CARG1, L
| bl extern lj_gc_step // (lua_State *L)
| ldr BASE, L->base
| mov lr, RA // Help return address predictor.
| ldr CFUNC:CARG3, [BASE, FRAME_FUNC]
| bx lr
| |
|//----------------------------------------------------------------------- |//-----------------------------------------------------------------------
|//-- Special dispatch targets ------------------------------------------- |//-- Special dispatch targets -------------------------------------------