mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Refactor string.reverse(), string.lower(), string.upper().
This commit is contained in:
parent
eeb204cd87
commit
61cb25b0ca
@ -96,10 +96,10 @@ lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
|||||||
lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
|
lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
|
||||||
lj_state.h lj_frame.h lj_bc.h lj_jit.h lj_ir.h
|
lj_state.h lj_frame.h lj_bc.h lj_jit.h lj_ir.h
|
||||||
lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||||
lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \
|
lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_func.h lj_tab.h \
|
||||||
lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \
|
lj_meta.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h \
|
||||||
lj_ccallback.h lj_ctype.h lj_gc.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
lj_jit.h lj_ir.h lj_ccallback.h lj_ctype.h lj_trace.h lj_dispatch.h \
|
||||||
lj_vm.h luajit.h
|
lj_traceerr.h lj_vm.h luajit.h
|
||||||
lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
|
lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
|
||||||
lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
|
lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
|
||||||
lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
|
lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
|
||||||
|
@ -135,8 +135,7 @@ LJLIB_ASM(string_rep)
|
|||||||
|
|
||||||
LJLIB_ASM(string_reverse)
|
LJLIB_ASM(string_reverse)
|
||||||
{
|
{
|
||||||
GCstr *s = lj_lib_checkstr(L, 1);
|
lj_lib_checkstr(L, 1);
|
||||||
lj_buf_tmp(L, s->len);
|
|
||||||
return FFH_RETRY;
|
return FFH_RETRY;
|
||||||
}
|
}
|
||||||
LJLIB_ASM_(string_lower)
|
LJLIB_ASM_(string_lower)
|
||||||
|
51
src/lj_buf.c
51
src/lj_buf.c
@ -34,7 +34,7 @@ LJ_NOINLINE void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en)
|
|||||||
char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
|
char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
|
||||||
{
|
{
|
||||||
SBuf *sb = &G(L)->tmpbuf;
|
SBuf *sb = &G(L)->tmpbuf;
|
||||||
setmref(sb->L, L);
|
setsbufL(sb, L);
|
||||||
return lj_buf_need(sb, sz);
|
return lj_buf_need(sb, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,12 +95,59 @@ SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o)
|
|||||||
setsbufP(sb, lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF), o));
|
setsbufP(sb, lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF), o));
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s)
|
||||||
|
{
|
||||||
|
MSize len = s->len;
|
||||||
|
char *p = lj_buf_more(sb, len), *e = p+len;
|
||||||
|
const char *q = strdata(s)+len-1;
|
||||||
|
while (p < e)
|
||||||
|
*p++ = *q--;
|
||||||
|
setsbufP(sb, p);
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s)
|
||||||
|
{
|
||||||
|
MSize len = s->len;
|
||||||
|
char *p = lj_buf_more(sb, len), *e = p+len;
|
||||||
|
const char *q = strdata(s);
|
||||||
|
for (; p < e; p++, q++) {
|
||||||
|
uint32_t c = *(unsigned char *)q;
|
||||||
|
#if LJ_TARGET_PPC
|
||||||
|
*p = c + ((c >= 'A' && c <= 'Z') << 5);
|
||||||
|
#else
|
||||||
|
if (c >= 'A' && c <= 'Z') c += 0x20;
|
||||||
|
*p = c;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
setsbufP(sb, p);
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s)
|
||||||
|
{
|
||||||
|
MSize len = s->len;
|
||||||
|
char *p = lj_buf_more(sb, len), *e = p+len;
|
||||||
|
const char *q = strdata(s);
|
||||||
|
for (; p < e; p++, q++) {
|
||||||
|
uint32_t c = *(unsigned char *)q;
|
||||||
|
#if LJ_TARGET_PPC
|
||||||
|
*p = c - ((c >= 'a' && c <= 'z') << 5);
|
||||||
|
#else
|
||||||
|
if (c >= 'a' && c <= 'z') c -= 0x20;
|
||||||
|
*p = c;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
setsbufP(sb, p);
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb)
|
GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb)
|
||||||
{
|
{
|
||||||
return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb));
|
return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
|
uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
|
||||||
{
|
{
|
||||||
|
@ -31,8 +31,11 @@ LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s);
|
|||||||
LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
|
LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
|
||||||
LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k);
|
LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k);
|
||||||
LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o);
|
LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o);
|
||||||
LJ_FUNC GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb);
|
|
||||||
#endif
|
#endif
|
||||||
|
LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s);
|
||||||
|
LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s);
|
||||||
|
LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s);
|
||||||
|
LJ_FUNCA GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb);
|
||||||
LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
|
LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
|
||||||
LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v);
|
LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v);
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
|
#include "lj_buf.h"
|
||||||
#include "lj_func.h"
|
#include "lj_func.h"
|
||||||
#include "lj_str.h"
|
#include "lj_str.h"
|
||||||
#include "lj_tab.h"
|
#include "lj_tab.h"
|
||||||
|
@ -37,7 +37,8 @@
|
|||||||
_(lj_meta_tset) _(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) \
|
_(lj_meta_tset) _(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) \
|
||||||
_(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \
|
_(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \
|
||||||
_(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \
|
_(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \
|
||||||
_(lj_tab_setinth) JITGOTDEF(_) FFIGOTDEF(_)
|
_(lj_tab_setinth) _(lj_buf_putstr_reverse) _(lj_buf_putstr_lower) \
|
||||||
|
_(lj_buf_putstr_upper) _(lj_buf_tostr) JITGOTDEF(_) FFIGOTDEF(_)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
#define GOTENUM(name) LJ_GOT_##name,
|
#define GOTENUM(name) LJ_GOT_##name,
|
||||||
|
@ -99,6 +99,7 @@
|
|||||||
|.type NODE, Node
|
|.type NODE, Node
|
||||||
|.type NARGS8, int
|
|.type NARGS8, int
|
||||||
|.type TRACE, GCtrace
|
|.type TRACE, GCtrace
|
||||||
|
|.type SBUF, SBuf
|
||||||
|
|
|
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
@ -1743,6 +1744,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| mov CARG1, L
|
| mov CARG1, L
|
||||||
| str PC, SAVE_PC
|
| str PC, SAVE_PC
|
||||||
| bl extern lj_str_new // (lua_State *L, char *str, size_t l)
|
| bl extern lj_str_new // (lua_State *L, char *str, size_t l)
|
||||||
|
|->fff_resstr:
|
||||||
| // Returns GCstr *.
|
| // Returns GCstr *.
|
||||||
| ldr BASE, L->base
|
| ldr BASE, L->base
|
||||||
| mvn CARG2, #~LJ_TSTR
|
| mvn CARG2, #~LJ_TSTR
|
||||||
@ -1813,56 +1815,28 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| bge <1
|
| bge <1
|
||||||
| b ->fff_newstr
|
| b ->fff_newstr
|
||||||
|
|
|
|
||||||
|.ffunc string_reverse
|
|.macro ffstring_op, name
|
||||||
|
| .ffunc string_ .. name
|
||||||
| ffgccheck
|
| ffgccheck
|
||||||
| ldrd CARG12, [BASE]
|
| ldr CARG3, [BASE, #4]
|
||||||
| cmp NARGS8:RC, #8
|
| cmp NARGS8:RC, #8
|
||||||
|
| ldr STR:CARG2, [BASE]
|
||||||
| blo ->fff_fallback
|
| blo ->fff_fallback
|
||||||
| checkstr CARG2, ->fff_fallback
|
| sub SBUF:CARG1, DISPATCH, #-DISPATCH_GL(tmpbuf)
|
||||||
| ldr CARG3, STR:CARG1->len
|
| checkstr CARG3, ->fff_fallback
|
||||||
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)]
|
| ldr CARG4, SBUF:CARG1->b
|
||||||
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)]
|
| str BASE, L->base
|
||||||
| mov CARG4, CARG3
|
| str PC, SAVE_PC
|
||||||
| add CARG1, STR:CARG1, #sizeof(GCstr)
|
| str L, SBUF:CARG1->L
|
||||||
| add INS, CARG2, CARG3
|
| str CARG4, SBUF:CARG1->p
|
||||||
| cmp RB, INS
|
| bl extern lj_buf_putstr_ .. name
|
||||||
| blo ->fff_fallback
|
| bl extern lj_buf_tostr
|
||||||
|1: // Reverse string copy.
|
| b ->fff_resstr
|
||||||
| ldrb RB, [CARG1], #1
|
|
||||||
| subs CARG4, CARG4, #1
|
|
||||||
| blt ->fff_newstr
|
|
||||||
| strb RB, [CARG2, CARG4]
|
|
||||||
| b <1
|
|
||||||
|
|
|
||||||
|.macro ffstring_case, name, lo
|
|
||||||
| .ffunc name
|
|
||||||
| ffgccheck
|
|
||||||
| ldrd CARG12, [BASE]
|
|
||||||
| cmp NARGS8:RC, #8
|
|
||||||
| blo ->fff_fallback
|
|
||||||
| checkstr CARG2, ->fff_fallback
|
|
||||||
| ldr CARG3, STR:CARG1->len
|
|
||||||
| ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)]
|
|
||||||
| ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)]
|
|
||||||
| mov CARG4, #0
|
|
||||||
| add CARG1, STR:CARG1, #sizeof(GCstr)
|
|
||||||
| add INS, CARG2, CARG3
|
|
||||||
| cmp RB, INS
|
|
||||||
| 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_op reverse
|
||||||
|ffstring_case string_upper, 97
|
|ffstring_op lower
|
||||||
|
|ffstring_op upper
|
||||||
|
|
|
|
||||||
|//-- Bit library --------------------------------------------------------
|
|//-- Bit library --------------------------------------------------------
|
||||||
|
|
|
|
||||||
|
@ -138,6 +138,7 @@
|
|||||||
|.type NODE, Node
|
|.type NODE, Node
|
||||||
|.type NARGS8, int
|
|.type NARGS8, int
|
||||||
|.type TRACE, GCtrace
|
|.type TRACE, GCtrace
|
||||||
|
|.type SBUF, SBuf
|
||||||
|
|
|
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
@ -1668,6 +1669,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|. move CARG1, L
|
|. move CARG1, L
|
||||||
| // Returns GCstr *.
|
| // Returns GCstr *.
|
||||||
| lw BASE, L->base
|
| lw BASE, L->base
|
||||||
|
|->fff_resstr:
|
||||||
| move CARG1, CRET1
|
| move CARG1, CRET1
|
||||||
| b ->fff_restv
|
| b ->fff_restv
|
||||||
|. li CARG3, LJ_TSTR
|
|. li CARG3, LJ_TSTR
|
||||||
@ -1756,63 +1758,32 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| b ->fff_newstr
|
| b ->fff_newstr
|
||||||
|. nop
|
|. nop
|
||||||
|
|
|
|
||||||
|.ffunc string_reverse
|
|.macro ffstring_op, name
|
||||||
|
| .ffunc string_ .. name
|
||||||
| ffgccheck
|
| ffgccheck
|
||||||
| lw CARG3, HI(BASE)
|
| lw CARG3, HI(BASE)
|
||||||
| lw STR:CARG1, LO(BASE)
|
| lw STR:CARG2, LO(BASE)
|
||||||
| beqz NARGS8:RC, ->fff_fallback
|
| beqz NARGS8:RC, ->fff_fallback
|
||||||
|. li AT, LJ_TSTR
|
|. li AT, LJ_TSTR
|
||||||
| bne CARG3, AT, ->fff_fallback
|
| bne CARG3, AT, ->fff_fallback
|
||||||
|. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
|. addiu SBUF:CARG1, DISPATCH, DISPATCH_GL(tmpbuf)
|
||||||
| lw CARG3, STR:CARG1->len
|
| load_got lj_buf_putstr_ .. name
|
||||||
| lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
| lw TMP0, SBUF:CARG1->b
|
||||||
| addiu CARG1, STR:CARG1, #STR
|
| sw L, SBUF:CARG1->L
|
||||||
| addu CARG4, CARG2, CARG3
|
| sw BASE, L->base
|
||||||
| sltu AT, TMP1, CARG4
|
| sw TMP0, SBUF:CARG1->p
|
||||||
| bnez AT, ->fff_fallback
|
| call_intern extern lj_buf_putstr_ .. name
|
||||||
|. addu TMP3, CARG1, CARG3
|
|. sw PC, SAVE_PC
|
||||||
|1: // Reverse string copy.
|
| load_got lj_buf_tostr
|
||||||
| lbu TMP1, 0(CARG1)
|
| call_intern lj_buf_tostr
|
||||||
| sltu AT, CARG1, TMP3
|
|. move SBUF:CARG1, SBUF:CRET1
|
||||||
| beqz AT, ->fff_newstr
|
| b ->fff_resstr
|
||||||
|. addiu CARG1, CARG1, 1
|
|. lw BASE, L->base
|
||||||
| addiu CARG4, CARG4, -1
|
|
||||||
| b <1
|
|
||||||
| sb TMP1, 0(CARG4)
|
|
||||||
|
|
|
||||||
|.macro ffstring_case, name, lo
|
|
||||||
| .ffunc name
|
|
||||||
| ffgccheck
|
|
||||||
| lw CARG3, HI(BASE)
|
|
||||||
| lw STR:CARG1, LO(BASE)
|
|
||||||
| beqz NARGS8:RC, ->fff_fallback
|
|
||||||
|. li AT, LJ_TSTR
|
|
||||||
| bne CARG3, AT, ->fff_fallback
|
|
||||||
|. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
|
||||||
| lw CARG3, STR:CARG1->len
|
|
||||||
| lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
|
||||||
| addiu CARG1, STR:CARG1, #STR
|
|
||||||
| addu TMP3, CARG2, CARG3
|
|
||||||
| sltu AT, TMP1, TMP3
|
|
||||||
| bnez AT, ->fff_fallback
|
|
||||||
|. addu TMP3, CARG1, CARG3
|
|
||||||
| move CARG4, CARG2
|
|
||||||
|1: // ASCII case conversion.
|
|
||||||
| lbu TMP1, 0(CARG1)
|
|
||||||
| sltu AT, CARG1, TMP3
|
|
||||||
| beqz AT, ->fff_newstr
|
|
||||||
|. addiu TMP0, TMP1, -lo
|
|
||||||
| xori TMP2, TMP1, 0x20
|
|
||||||
| sltiu AT, TMP0, 26
|
|
||||||
| movn TMP1, TMP2, AT
|
|
||||||
| addiu CARG1, CARG1, 1
|
|
||||||
| sb TMP1, 0(CARG4)
|
|
||||||
| b <1
|
|
||||||
|. addiu CARG4, CARG4, 1
|
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
|ffstring_case string_lower, 65
|
|ffstring_op reverse
|
||||||
|ffstring_case string_upper, 97
|
|ffstring_op lower
|
||||||
|
|ffstring_op upper
|
||||||
|
|
|
|
||||||
|//-- Bit library --------------------------------------------------------
|
|//-- Bit library --------------------------------------------------------
|
||||||
|
|
|
|
||||||
|
@ -293,6 +293,7 @@
|
|||||||
|.type NODE, Node
|
|.type NODE, Node
|
||||||
|.type NARGS8, int
|
|.type NARGS8, int
|
||||||
|.type TRACE, GCtrace
|
|.type TRACE, GCtrace
|
||||||
|
|.type SBUF, SBuf
|
||||||
|
|
|
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
@ -2103,6 +2104,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| stp BASE, L->base
|
| stp BASE, L->base
|
||||||
| stw PC, SAVE_PC
|
| stw PC, SAVE_PC
|
||||||
| bl extern lj_str_new // (lua_State *L, char *str, size_t l)
|
| bl extern lj_str_new // (lua_State *L, char *str, size_t l)
|
||||||
|
|->fff_resstr:
|
||||||
| // Returns GCstr *.
|
| // Returns GCstr *.
|
||||||
| lp BASE, L->base
|
| lp BASE, L->base
|
||||||
| li CARG3, LJ_TSTR
|
| li CARG3, LJ_TSTR
|
||||||
@ -2223,66 +2225,29 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| li CARG3, LJ_TSTR
|
| li CARG3, LJ_TSTR
|
||||||
| b ->fff_restv
|
| b ->fff_restv
|
||||||
|
|
|
|
||||||
|.ffunc string_reverse
|
|.macro ffstring_op, name
|
||||||
|
| .ffunc string_ .. name
|
||||||
| ffgccheck
|
| ffgccheck
|
||||||
| cmplwi NARGS8:RC, 8
|
| cmplwi NARGS8:RC, 8
|
||||||
| lwz CARG3, 0(BASE)
|
| lwz CARG3, 0(BASE)
|
||||||
| lwz STR:CARG1, 4(BASE)
|
| lwz STR:CARG2, 4(BASE)
|
||||||
| blt ->fff_fallback
|
| blt ->fff_fallback
|
||||||
| checkstr CARG3
|
| checkstr CARG3
|
||||||
| lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
| la SBUF:CARG1, DISPATCH_GL(tmpbuf)(DISPATCH)
|
||||||
| lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
|
||||||
| bne ->fff_fallback
|
| bne ->fff_fallback
|
||||||
| lwz CARG3, STR:CARG1->len
|
| lwz TMP0, SBUF:CARG1->b
|
||||||
| la CARG1, #STR(STR:CARG1)
|
| stw L, SBUF:CARG1->L
|
||||||
| li TMP2, 0
|
| stp BASE, L->base
|
||||||
| add TMP3, CARG2, CARG3
|
| stw PC, SAVE_PC
|
||||||
| cmplw TMP1, TMP3
|
| stw TMP0, SBUF:CARG1->p
|
||||||
| subi TMP3, CARG3, 1
|
| bl extern lj_buf_putstr_ .. name
|
||||||
| blt ->fff_fallback
|
| bl extern lj_buf_tostr
|
||||||
|1: // Reverse string copy.
|
| b ->fff_resstr
|
||||||
| cmpwi TMP3, 0
|
|
||||||
| lbzx TMP1, CARG1, TMP2
|
|
||||||
| blty ->fff_newstr
|
|
||||||
| stbx TMP1, CARG2, TMP3
|
|
||||||
| subi TMP3, TMP3, 1
|
|
||||||
| addi TMP2, TMP2, 1
|
|
||||||
| b <1
|
|
||||||
|
|
|
||||||
|.macro ffstring_case, name, lo
|
|
||||||
| .ffunc name
|
|
||||||
| ffgccheck
|
|
||||||
| cmplwi NARGS8:RC, 8
|
|
||||||
| lwz CARG3, 0(BASE)
|
|
||||||
| lwz STR:CARG1, 4(BASE)
|
|
||||||
| blt ->fff_fallback
|
|
||||||
| checkstr CARG3
|
|
||||||
| lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
|
|
||||||
| lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
|
|
||||||
| bne ->fff_fallback
|
|
||||||
| lwz CARG3, STR:CARG1->len
|
|
||||||
| la CARG1, #STR(STR:CARG1)
|
|
||||||
| li TMP2, 0
|
|
||||||
| add TMP3, CARG2, CARG3
|
|
||||||
| cmplw TMP1, TMP3
|
|
||||||
| blt ->fff_fallback
|
|
||||||
|1: // ASCII case conversion.
|
|
||||||
| cmplw TMP2, CARG3
|
|
||||||
| lbzx TMP1, CARG1, TMP2
|
|
||||||
| bgey ->fff_newstr
|
|
||||||
| subi TMP0, TMP1, lo
|
|
||||||
| xori TMP3, TMP1, 0x20
|
|
||||||
| addic TMP0, TMP0, -26
|
|
||||||
| subfe TMP3, TMP3, TMP3
|
|
||||||
| rlwinm TMP3, TMP3, 0, 26, 26 // x &= 0x20.
|
|
||||||
| xor TMP1, TMP1, TMP3
|
|
||||||
| stbx TMP1, CARG2, TMP2
|
|
||||||
| addi TMP2, TMP2, 1
|
|
||||||
| b <1
|
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
|ffstring_case string_lower, 65
|
|ffstring_op reverse
|
||||||
|ffstring_case string_upper, 97
|
|ffstring_op lower
|
||||||
|
|ffstring_op upper
|
||||||
|
|
|
|
||||||
|//-- Bit library --------------------------------------------------------
|
|//-- Bit library --------------------------------------------------------
|
||||||
|
|
|
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
|.type NODE, Node
|
|.type NODE, Node
|
||||||
|.type NARGS, int
|
|.type NARGS, int
|
||||||
|.type TRACE, GCtrace
|
|.type TRACE, GCtrace
|
||||||
|
|.type SBUF, SBuf
|
||||||
|
|
|
|
||||||
|// Stack layout while in interpreter. Must match with lj_frame.h.
|
|// Stack layout while in interpreter. Must match with lj_frame.h.
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
@ -2258,6 +2259,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|.endif
|
|.endif
|
||||||
| mov SAVE_PC, PC
|
| mov SAVE_PC, PC
|
||||||
| call extern lj_str_new // (lua_State *L, char *str, size_t l)
|
| call extern lj_str_new // (lua_State *L, char *str, size_t l)
|
||||||
|
|->fff_resstr:
|
||||||
| // GCstr * returned in eax (RD).
|
| // GCstr * returned in eax (RD).
|
||||||
| mov BASE, L:RB->base
|
| mov BASE, L:RB->base
|
||||||
| mov PC, [BASE-4]
|
| mov PC, [BASE-4]
|
||||||
@ -2373,69 +2375,27 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.b)]
|
| mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.b)]
|
||||||
| jmp ->fff_newstr
|
| jmp ->fff_newstr
|
||||||
|
|
|
|
||||||
|.ffunc_1 string_reverse
|
|.macro ffstring_op, name
|
||||||
|
| .ffunc_1 string_ .. name
|
||||||
| ffgccheck
|
| ffgccheck
|
||||||
| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
|
| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
|
||||||
| mov STR:RB, [BASE]
|
| mov L:RB, SAVE_L
|
||||||
| mov RC, STR:RB->len
|
| lea SBUF:FCARG1, [DISPATCH+DISPATCH_GL(tmpbuf)]
|
||||||
| test RC, RC
|
| mov L:RB->base, BASE
|
||||||
| jz ->fff_emptystr // Zero length string?
|
| mov STR:FCARG2, [BASE] // Caveat: FCARG2 == BASE
|
||||||
| mov TMP2, PC // Need another temp register.
|
| mov RC, SBUF:FCARG1->b
|
||||||
| mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.b)]
|
| mov SBUF:FCARG1->L, L:RB
|
||||||
| lea RA, [PC+RC]
|
| mov SBUF:FCARG1->p, RC
|
||||||
| cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RA; jb ->fff_fallback_1
|
| mov SAVE_PC, PC
|
||||||
| add RB, #STR
|
| call extern lj_buf_putstr_ .. name
|
||||||
|.if X64
|
| mov FCARG1, eax
|
||||||
| mov TMP3, RC
|
| call extern lj_buf_tostr
|
||||||
|.else
|
| jmp ->fff_resstr
|
||||||
| mov ARG3, RC
|
|
||||||
|.endif
|
|
||||||
|1:
|
|
||||||
| movzx RA, byte [RB]
|
|
||||||
| add RB, 1
|
|
||||||
| sub RC, 1
|
|
||||||
| mov [PC+RC], RAL
|
|
||||||
| jnz <1
|
|
||||||
| mov RD, PC
|
|
||||||
| mov PC, TMP2
|
|
||||||
| jmp ->fff_newstr
|
|
||||||
|
|
|
||||||
|.macro ffstring_case, name, lo, hi
|
|
||||||
| .ffunc_1 name
|
|
||||||
| ffgccheck
|
|
||||||
| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
|
|
||||||
| mov TMP2, PC // Need another temp register.
|
|
||||||
| mov STR:RB, [BASE]
|
|
||||||
| mov RC, STR:RB->len
|
|
||||||
| mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.b)]
|
|
||||||
| lea RA, [PC+RC]
|
|
||||||
| cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RA; jb ->fff_fallback_1
|
|
||||||
| add RB, #STR
|
|
||||||
|.if X64
|
|
||||||
| mov TMP3, RC
|
|
||||||
|.else
|
|
||||||
| mov ARG3, RC
|
|
||||||
|.endif
|
|
||||||
| jmp >3
|
|
||||||
|1: // ASCII case conversion. Yes, this is suboptimal code (do you care?).
|
|
||||||
| movzx RA, byte [RB+RC]
|
|
||||||
| cmp RA, lo
|
|
||||||
| jb >2
|
|
||||||
| cmp RA, hi
|
|
||||||
| ja >2
|
|
||||||
| xor RA, 0x20
|
|
||||||
|2:
|
|
||||||
| mov [PC+RC], RAL
|
|
||||||
|3:
|
|
||||||
| sub RC, 1
|
|
||||||
| jns <1
|
|
||||||
| mov RD, PC
|
|
||||||
| mov PC, TMP2
|
|
||||||
| jmp ->fff_newstr
|
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
|ffstring_case string_lower, 0x41, 0x5a
|
|ffstring_op reverse
|
||||||
|ffstring_case string_upper, 0x61, 0x7a
|
|ffstring_op lower
|
||||||
|
|ffstring_op upper
|
||||||
|
|
|
|
||||||
|//-- Bit library --------------------------------------------------------
|
|//-- Bit library --------------------------------------------------------
|
||||||
|
|
|
|
||||||
|
Loading…
Reference in New Issue
Block a user