aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-04-26 00:31:10 +0200
committerMike Pall <mike>2013-04-26 00:31:10 +0200
commit61cb25b0ca19f75be49373969d6dc3daa646d3aa (patch)
treecdd154fec85b54e42c429289791c9aa86877b3df
parenteeb204cd87a58f8a6e29022ea30aaba877acb2e0 (diff)
downloadluajit-61cb25b0ca19f75be49373969d6dc3daa646d3aa.tar.gz
luajit-61cb25b0ca19f75be49373969d6dc3daa646d3aa.tar.bz2
luajit-61cb25b0ca19f75be49373969d6dc3daa646d3aa.zip
Refactor string.reverse(), string.lower(), string.upper().
-rw-r--r--src/Makefile.dep8
-rw-r--r--src/lib_string.c3
-rw-r--r--src/lj_buf.c51
-rw-r--r--src/lj_buf.h5
-rw-r--r--src/lj_dispatch.c1
-rw-r--r--src/lj_dispatch.h3
-rw-r--r--src/vm_arm.dasc64
-rw-r--r--src/vm_mips.dasc71
-rw-r--r--src/vm_ppc.dasc69
-rw-r--r--src/vm_x86.dasc78
10 files changed, 137 insertions, 216 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep
index c501db44..a29b396a 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -96,10 +96,10 @@ lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
96 lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \ 96 lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
97 lj_state.h lj_frame.h lj_bc.h lj_jit.h lj_ir.h 97 lj_state.h lj_frame.h lj_bc.h lj_jit.h lj_ir.h
98lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 98lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
99 lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \ 99 lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_func.h lj_tab.h \
100 lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \ 100 lj_meta.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h \
101 lj_ccallback.h lj_ctype.h lj_gc.h lj_trace.h lj_dispatch.h lj_traceerr.h \ 101 lj_jit.h lj_ir.h lj_ccallback.h lj_ctype.h lj_trace.h lj_dispatch.h \
102 lj_vm.h luajit.h 102 lj_traceerr.h lj_vm.h luajit.h
103lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \ 103lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
104 lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \ 104 lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
105 lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \ 105 lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
diff --git a/src/lib_string.c b/src/lib_string.c
index 27e0d594..c8243d6c 100644
--- a/src/lib_string.c
+++ b/src/lib_string.c
@@ -135,8 +135,7 @@ LJLIB_ASM(string_rep)
135 135
136LJLIB_ASM(string_reverse) 136LJLIB_ASM(string_reverse)
137{ 137{
138 GCstr *s = lj_lib_checkstr(L, 1); 138 lj_lib_checkstr(L, 1);
139 lj_buf_tmp(L, s->len);
140 return FFH_RETRY; 139 return FFH_RETRY;
141} 140}
142LJLIB_ASM_(string_lower) 141LJLIB_ASM_(string_lower)
diff --git a/src/lj_buf.c b/src/lj_buf.c
index 67525694..32ed52b9 100644
--- a/src/lj_buf.c
+++ b/src/lj_buf.c
@@ -34,7 +34,7 @@ LJ_NOINLINE void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en)
34char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz) 34char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz)
35{ 35{
36 SBuf *sb = &G(L)->tmpbuf; 36 SBuf *sb = &G(L)->tmpbuf;
37 setmref(sb->L, L); 37 setsbufL(sb, L);
38 return lj_buf_need(sb, sz); 38 return lj_buf_need(sb, sz);
39} 39}
40 40
@@ -95,12 +95,59 @@ SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o)
95 setsbufP(sb, lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF), o)); 95 setsbufP(sb, lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF), o));
96 return sb; 96 return sb;
97} 97}
98#endif
99
100SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s)
101{
102 MSize len = s->len;
103 char *p = lj_buf_more(sb, len), *e = p+len;
104 const char *q = strdata(s)+len-1;
105 while (p < e)
106 *p++ = *q--;
107 setsbufP(sb, p);
108 return sb;
109}
110
111SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s)
112{
113 MSize len = s->len;
114 char *p = lj_buf_more(sb, len), *e = p+len;
115 const char *q = strdata(s);
116 for (; p < e; p++, q++) {
117 uint32_t c = *(unsigned char *)q;
118#if LJ_TARGET_PPC
119 *p = c + ((c >= 'A' && c <= 'Z') << 5);
120#else
121 if (c >= 'A' && c <= 'Z') c += 0x20;
122 *p = c;
123#endif
124 }
125 setsbufP(sb, p);
126 return sb;
127}
128
129SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s)
130{
131 MSize len = s->len;
132 char *p = lj_buf_more(sb, len), *e = p+len;
133 const char *q = strdata(s);
134 for (; p < e; p++, q++) {
135 uint32_t c = *(unsigned char *)q;
136#if LJ_TARGET_PPC
137 *p = c - ((c >= 'a' && c <= 'z') << 5);
138#else
139 if (c >= 'a' && c <= 'z') c -= 0x20;
140 *p = c;
141#endif
142 }
143 setsbufP(sb, p);
144 return sb;
145}
98 146
99GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb) 147GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb)
100{ 148{
101 return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb)); 149 return lj_str_new(sbufL(sb), sbufB(sb), sbuflen(sb));
102} 150}
103#endif
104 151
105uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp) 152uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp)
106{ 153{
diff --git a/src/lj_buf.h b/src/lj_buf.h
index 426ec720..98bcad20 100644
--- a/src/lj_buf.h
+++ b/src/lj_buf.h
@@ -31,8 +31,11 @@ LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s);
31LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c); 31LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c);
32LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k); 32LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k);
33LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o); 33LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o);
34LJ_FUNC GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb);
35#endif 34#endif
35LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s);
36LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s);
37LJ_FUNCA SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s);
38LJ_FUNCA GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb);
36LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp); 39LJ_FUNC uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp);
37LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v); 40LJ_FUNC char * LJ_FASTCALL lj_buf_wuleb128(char *p, uint32_t v);
38 41
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index d57f1a6f..c144afce 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -8,6 +8,7 @@
8 8
9#include "lj_obj.h" 9#include "lj_obj.h"
10#include "lj_err.h" 10#include "lj_err.h"
11#include "lj_buf.h"
11#include "lj_func.h" 12#include "lj_func.h"
12#include "lj_str.h" 13#include "lj_str.h"
13#include "lj_tab.h" 14#include "lj_tab.h"
diff --git a/src/lj_dispatch.h b/src/lj_dispatch.h
index a03804af..1368594a 100644
--- a/src/lj_dispatch.h
+++ b/src/lj_dispatch.h
@@ -37,7 +37,8 @@
37 _(lj_meta_tset) _(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) \ 37 _(lj_meta_tset) _(lj_state_growstack) _(lj_str_fromnum) _(lj_str_fromnumber) \
38 _(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \ 38 _(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \
39 _(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \ 39 _(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \
40 _(lj_tab_setinth) JITGOTDEF(_) FFIGOTDEF(_) 40 _(lj_tab_setinth) _(lj_buf_putstr_reverse) _(lj_buf_putstr_lower) \
41 _(lj_buf_putstr_upper) _(lj_buf_tostr) JITGOTDEF(_) FFIGOTDEF(_)
41 42
42enum { 43enum {
43#define GOTENUM(name) LJ_GOT_##name, 44#define GOTENUM(name) LJ_GOT_##name,
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc
index 4579b263..5a15c409 100644
--- a/src/vm_arm.dasc
+++ b/src/vm_arm.dasc
@@ -99,6 +99,7 @@
99|.type NODE, Node 99|.type NODE, Node
100|.type NARGS8, int 100|.type NARGS8, int
101|.type TRACE, GCtrace 101|.type TRACE, GCtrace
102|.type SBUF, SBuf
102| 103|
103|//----------------------------------------------------------------------- 104|//-----------------------------------------------------------------------
104| 105|
@@ -1743,6 +1744,7 @@ static void build_subroutines(BuildCtx *ctx)
1743 | mov CARG1, L 1744 | mov CARG1, L
1744 | str PC, SAVE_PC 1745 | str PC, SAVE_PC
1745 | bl extern lj_str_new // (lua_State *L, char *str, size_t l) 1746 | bl extern lj_str_new // (lua_State *L, char *str, size_t l)
1747 |->fff_resstr:
1746 | // Returns GCstr *. 1748 | // Returns GCstr *.
1747 | ldr BASE, L->base 1749 | ldr BASE, L->base
1748 | mvn CARG2, #~LJ_TSTR 1750 | mvn CARG2, #~LJ_TSTR
@@ -1813,56 +1815,28 @@ static void build_subroutines(BuildCtx *ctx)
1813 | bge <1 1815 | bge <1
1814 | b ->fff_newstr 1816 | b ->fff_newstr
1815 | 1817 |
1816 |.ffunc string_reverse 1818 |.macro ffstring_op, name
1819 | .ffunc string_ .. name
1817 | ffgccheck 1820 | ffgccheck
1818 | ldrd CARG12, [BASE] 1821 | ldr CARG3, [BASE, #4]
1819 | cmp NARGS8:RC, #8
1820 | blo ->fff_fallback
1821 | checkstr CARG2, ->fff_fallback
1822 | ldr CARG3, STR:CARG1->len
1823 | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)]
1824 | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)]
1825 | mov CARG4, CARG3
1826 | add CARG1, STR:CARG1, #sizeof(GCstr)
1827 | add INS, CARG2, CARG3
1828 | cmp RB, INS
1829 | blo ->fff_fallback
1830 |1: // Reverse string copy.
1831 | ldrb RB, [CARG1], #1
1832 | subs CARG4, CARG4, #1
1833 | blt ->fff_newstr
1834 | strb RB, [CARG2, CARG4]
1835 | b <1
1836 |
1837 |.macro ffstring_case, name, lo
1838 | .ffunc name
1839 | ffgccheck
1840 | ldrd CARG12, [BASE]
1841 | cmp NARGS8:RC, #8 1822 | cmp NARGS8:RC, #8
1823 | ldr STR:CARG2, [BASE]
1842 | blo ->fff_fallback 1824 | blo ->fff_fallback
1843 | checkstr CARG2, ->fff_fallback 1825 | sub SBUF:CARG1, DISPATCH, #-DISPATCH_GL(tmpbuf)
1844 | ldr CARG3, STR:CARG1->len 1826 | checkstr CARG3, ->fff_fallback
1845 | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.b)] 1827 | ldr CARG4, SBUF:CARG1->b
1846 | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.e)] 1828 | str BASE, L->base
1847 | mov CARG4, #0 1829 | str PC, SAVE_PC
1848 | add CARG1, STR:CARG1, #sizeof(GCstr) 1830 | str L, SBUF:CARG1->L
1849 | add INS, CARG2, CARG3 1831 | str CARG4, SBUF:CARG1->p
1850 | cmp RB, INS 1832 | bl extern lj_buf_putstr_ .. name
1851 | blo ->fff_fallback 1833 | bl extern lj_buf_tostr
1852 |1: // ASCII case conversion. 1834 | b ->fff_resstr
1853 | ldrb RB, [CARG1, CARG4]
1854 | cmp CARG4, CARG3
1855 | bhs ->fff_newstr
1856 | sub RC, RB, #lo
1857 | cmp RC, #26
1858 | eorlo RB, RB, #0x20
1859 | strb RB, [CARG2, CARG4]
1860 | add CARG4, CARG4, #1
1861 | b <1
1862 |.endmacro 1835 |.endmacro
1863 | 1836 |
1864 |ffstring_case string_lower, 65 1837 |ffstring_op reverse
1865 |ffstring_case string_upper, 97 1838 |ffstring_op lower
1839 |ffstring_op upper
1866 | 1840 |
1867 |//-- Bit library -------------------------------------------------------- 1841 |//-- Bit library --------------------------------------------------------
1868 | 1842 |
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc
index c4f01e81..fa53a554 100644
--- a/src/vm_mips.dasc
+++ b/src/vm_mips.dasc
@@ -138,6 +138,7 @@
138|.type NODE, Node 138|.type NODE, Node
139|.type NARGS8, int 139|.type NARGS8, int
140|.type TRACE, GCtrace 140|.type TRACE, GCtrace
141|.type SBUF, SBuf
141| 142|
142|//----------------------------------------------------------------------- 143|//-----------------------------------------------------------------------
143| 144|
@@ -1668,6 +1669,7 @@ static void build_subroutines(BuildCtx *ctx)
1668 |. move CARG1, L 1669 |. move CARG1, L
1669 | // Returns GCstr *. 1670 | // Returns GCstr *.
1670 | lw BASE, L->base 1671 | lw BASE, L->base
1672 |->fff_resstr:
1671 | move CARG1, CRET1 1673 | move CARG1, CRET1
1672 | b ->fff_restv 1674 | b ->fff_restv
1673 |. li CARG3, LJ_TSTR 1675 |. li CARG3, LJ_TSTR
@@ -1756,63 +1758,32 @@ static void build_subroutines(BuildCtx *ctx)
1756 | b ->fff_newstr 1758 | b ->fff_newstr
1757 |. nop 1759 |. nop
1758 | 1760 |
1759 |.ffunc string_reverse 1761 |.macro ffstring_op, name
1762 | .ffunc string_ .. name
1760 | ffgccheck 1763 | ffgccheck
1761 | lw CARG3, HI(BASE) 1764 | lw CARG3, HI(BASE)
1762 | lw STR:CARG1, LO(BASE) 1765 | lw STR:CARG2, LO(BASE)
1763 | beqz NARGS8:RC, ->fff_fallback 1766 | beqz NARGS8:RC, ->fff_fallback
1764 |. li AT, LJ_TSTR 1767 |. li AT, LJ_TSTR
1765 | bne CARG3, AT, ->fff_fallback 1768 | bne CARG3, AT, ->fff_fallback
1766 |. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) 1769 |. addiu SBUF:CARG1, DISPATCH, DISPATCH_GL(tmpbuf)
1767 | lw CARG3, STR:CARG1->len 1770 | load_got lj_buf_putstr_ .. name
1768 | lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH) 1771 | lw TMP0, SBUF:CARG1->b
1769 | addiu CARG1, STR:CARG1, #STR 1772 | sw L, SBUF:CARG1->L
1770 | addu CARG4, CARG2, CARG3 1773 | sw BASE, L->base
1771 | sltu AT, TMP1, CARG4 1774 | sw TMP0, SBUF:CARG1->p
1772 | bnez AT, ->fff_fallback 1775 | call_intern extern lj_buf_putstr_ .. name
1773 |. addu TMP3, CARG1, CARG3 1776 |. sw PC, SAVE_PC
1774 |1: // Reverse string copy. 1777 | load_got lj_buf_tostr
1775 | lbu TMP1, 0(CARG1) 1778 | call_intern lj_buf_tostr
1776 | sltu AT, CARG1, TMP3 1779 |. move SBUF:CARG1, SBUF:CRET1
1777 | beqz AT, ->fff_newstr 1780 | b ->fff_resstr
1778 |. addiu CARG1, CARG1, 1 1781 |. lw BASE, L->base
1779 | addiu CARG4, CARG4, -1
1780 | b <1
1781 | sb TMP1, 0(CARG4)
1782 |
1783 |.macro ffstring_case, name, lo
1784 | .ffunc name
1785 | ffgccheck
1786 | lw CARG3, HI(BASE)
1787 | lw STR:CARG1, LO(BASE)
1788 | beqz NARGS8:RC, ->fff_fallback
1789 |. li AT, LJ_TSTR
1790 | bne CARG3, AT, ->fff_fallback
1791 |. lw CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
1792 | lw CARG3, STR:CARG1->len
1793 | lw TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
1794 | addiu CARG1, STR:CARG1, #STR
1795 | addu TMP3, CARG2, CARG3
1796 | sltu AT, TMP1, TMP3
1797 | bnez AT, ->fff_fallback
1798 |. addu TMP3, CARG1, CARG3
1799 | move CARG4, CARG2
1800 |1: // ASCII case conversion.
1801 | lbu TMP1, 0(CARG1)
1802 | sltu AT, CARG1, TMP3
1803 | beqz AT, ->fff_newstr
1804 |. addiu TMP0, TMP1, -lo
1805 | xori TMP2, TMP1, 0x20
1806 | sltiu AT, TMP0, 26
1807 | movn TMP1, TMP2, AT
1808 | addiu CARG1, CARG1, 1
1809 | sb TMP1, 0(CARG4)
1810 | b <1
1811 |. addiu CARG4, CARG4, 1
1812 |.endmacro 1782 |.endmacro
1813 | 1783 |
1814 |ffstring_case string_lower, 65 1784 |ffstring_op reverse
1815 |ffstring_case string_upper, 97 1785 |ffstring_op lower
1786 |ffstring_op upper
1816 | 1787 |
1817 |//-- Bit library -------------------------------------------------------- 1788 |//-- Bit library --------------------------------------------------------
1818 | 1789 |
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc
index c85f1f10..ac399900 100644
--- a/src/vm_ppc.dasc
+++ b/src/vm_ppc.dasc
@@ -293,6 +293,7 @@
293|.type NODE, Node 293|.type NODE, Node
294|.type NARGS8, int 294|.type NARGS8, int
295|.type TRACE, GCtrace 295|.type TRACE, GCtrace
296|.type SBUF, SBuf
296| 297|
297|//----------------------------------------------------------------------- 298|//-----------------------------------------------------------------------
298| 299|
@@ -2103,6 +2104,7 @@ static void build_subroutines(BuildCtx *ctx)
2103 | stp BASE, L->base 2104 | stp BASE, L->base
2104 | stw PC, SAVE_PC 2105 | stw PC, SAVE_PC
2105 | bl extern lj_str_new // (lua_State *L, char *str, size_t l) 2106 | bl extern lj_str_new // (lua_State *L, char *str, size_t l)
2107 |->fff_resstr:
2106 | // Returns GCstr *. 2108 | // Returns GCstr *.
2107 | lp BASE, L->base 2109 | lp BASE, L->base
2108 | li CARG3, LJ_TSTR 2110 | li CARG3, LJ_TSTR
@@ -2223,66 +2225,29 @@ static void build_subroutines(BuildCtx *ctx)
2223 | li CARG3, LJ_TSTR 2225 | li CARG3, LJ_TSTR
2224 | b ->fff_restv 2226 | b ->fff_restv
2225 | 2227 |
2226 |.ffunc string_reverse 2228 |.macro ffstring_op, name
2229 | .ffunc string_ .. name
2227 | ffgccheck 2230 | ffgccheck
2228 | cmplwi NARGS8:RC, 8 2231 | cmplwi NARGS8:RC, 8
2229 | lwz CARG3, 0(BASE) 2232 | lwz CARG3, 0(BASE)
2230 | lwz STR:CARG1, 4(BASE) 2233 | lwz STR:CARG2, 4(BASE)
2231 | blt ->fff_fallback 2234 | blt ->fff_fallback
2232 | checkstr CARG3 2235 | checkstr CARG3
2233 | lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH) 2236 | la SBUF:CARG1, DISPATCH_GL(tmpbuf)(DISPATCH)
2234 | lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
2235 | bne ->fff_fallback 2237 | bne ->fff_fallback
2236 | lwz CARG3, STR:CARG1->len 2238 | lwz TMP0, SBUF:CARG1->b
2237 | la CARG1, #STR(STR:CARG1) 2239 | stw L, SBUF:CARG1->L
2238 | li TMP2, 0 2240 | stp BASE, L->base
2239 | add TMP3, CARG2, CARG3 2241 | stw PC, SAVE_PC
2240 | cmplw TMP1, TMP3 2242 | stw TMP0, SBUF:CARG1->p
2241 | subi TMP3, CARG3, 1 2243 | bl extern lj_buf_putstr_ .. name
2242 | blt ->fff_fallback 2244 | bl extern lj_buf_tostr
2243 |1: // Reverse string copy. 2245 | b ->fff_resstr
2244 | cmpwi TMP3, 0
2245 | lbzx TMP1, CARG1, TMP2
2246 | blty ->fff_newstr
2247 | stbx TMP1, CARG2, TMP3
2248 | subi TMP3, TMP3, 1
2249 | addi TMP2, TMP2, 1
2250 | b <1
2251 |
2252 |.macro ffstring_case, name, lo
2253 | .ffunc name
2254 | ffgccheck
2255 | cmplwi NARGS8:RC, 8
2256 | lwz CARG3, 0(BASE)
2257 | lwz STR:CARG1, 4(BASE)
2258 | blt ->fff_fallback
2259 | checkstr CARG3
2260 | lwz CARG2, DISPATCH_GL(tmpbuf.b)(DISPATCH)
2261 | lwz TMP1, DISPATCH_GL(tmpbuf.e)(DISPATCH)
2262 | bne ->fff_fallback
2263 | lwz CARG3, STR:CARG1->len
2264 | la CARG1, #STR(STR:CARG1)
2265 | li TMP2, 0
2266 | add TMP3, CARG2, CARG3
2267 | cmplw TMP1, TMP3
2268 | blt ->fff_fallback
2269 |1: // ASCII case conversion.
2270 | cmplw TMP2, CARG3
2271 | lbzx TMP1, CARG1, TMP2
2272 | bgey ->fff_newstr
2273 | subi TMP0, TMP1, lo
2274 | xori TMP3, TMP1, 0x20
2275 | addic TMP0, TMP0, -26
2276 | subfe TMP3, TMP3, TMP3
2277 | rlwinm TMP3, TMP3, 0, 26, 26 // x &= 0x20.
2278 | xor TMP1, TMP1, TMP3
2279 | stbx TMP1, CARG2, TMP2
2280 | addi TMP2, TMP2, 1
2281 | b <1
2282 |.endmacro 2246 |.endmacro
2283 | 2247 |
2284 |ffstring_case string_lower, 65 2248 |ffstring_op reverse
2285 |ffstring_case string_upper, 97 2249 |ffstring_op lower
2250 |ffstring_op upper
2286 | 2251 |
2287 |//-- Bit library -------------------------------------------------------- 2252 |//-- Bit library --------------------------------------------------------
2288 | 2253 |
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
index 8ed55fd2..8bbeaa2b 100644
--- a/src/vm_x86.dasc
+++ b/src/vm_x86.dasc
@@ -115,6 +115,7 @@
115|.type NODE, Node 115|.type NODE, Node
116|.type NARGS, int 116|.type NARGS, int
117|.type TRACE, GCtrace 117|.type TRACE, GCtrace
118|.type SBUF, SBuf
118| 119|
119|// Stack layout while in interpreter. Must match with lj_frame.h. 120|// Stack layout while in interpreter. Must match with lj_frame.h.
120|//----------------------------------------------------------------------- 121|//-----------------------------------------------------------------------
@@ -2258,6 +2259,7 @@ static void build_subroutines(BuildCtx *ctx)
2258 |.endif 2259 |.endif
2259 | mov SAVE_PC, PC 2260 | mov SAVE_PC, PC
2260 | call extern lj_str_new // (lua_State *L, char *str, size_t l) 2261 | call extern lj_str_new // (lua_State *L, char *str, size_t l)
2262 |->fff_resstr:
2261 | // GCstr * returned in eax (RD). 2263 | // GCstr * returned in eax (RD).
2262 | mov BASE, L:RB->base 2264 | mov BASE, L:RB->base
2263 | mov PC, [BASE-4] 2265 | mov PC, [BASE-4]
@@ -2373,69 +2375,27 @@ static void build_subroutines(BuildCtx *ctx)
2373 | mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.b)] 2375 | mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.b)]
2374 | jmp ->fff_newstr 2376 | jmp ->fff_newstr
2375 | 2377 |
2376 |.ffunc_1 string_reverse 2378 |.macro ffstring_op, name
2379 | .ffunc_1 string_ .. name
2377 | ffgccheck 2380 | ffgccheck
2378 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback 2381 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2379 | mov STR:RB, [BASE] 2382 | mov L:RB, SAVE_L
2380 | mov RC, STR:RB->len 2383 | lea SBUF:FCARG1, [DISPATCH+DISPATCH_GL(tmpbuf)]
2381 | test RC, RC 2384 | mov L:RB->base, BASE
2382 | jz ->fff_emptystr // Zero length string? 2385 | mov STR:FCARG2, [BASE] // Caveat: FCARG2 == BASE
2383 | mov TMP2, PC // Need another temp register. 2386 | mov RC, SBUF:FCARG1->b
2384 | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.b)] 2387 | mov SBUF:FCARG1->L, L:RB
2385 | lea RA, [PC+RC] 2388 | mov SBUF:FCARG1->p, RC
2386 | cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RA; jb ->fff_fallback_1 2389 | mov SAVE_PC, PC
2387 | add RB, #STR 2390 | call extern lj_buf_putstr_ .. name
2388 |.if X64 2391 | mov FCARG1, eax
2389 | mov TMP3, RC 2392 | call extern lj_buf_tostr
2390 |.else 2393 | jmp ->fff_resstr
2391 | mov ARG3, RC
2392 |.endif
2393 |1:
2394 | movzx RA, byte [RB]
2395 | add RB, 1
2396 | sub RC, 1
2397 | mov [PC+RC], RAL
2398 | jnz <1
2399 | mov RD, PC
2400 | mov PC, TMP2
2401 | jmp ->fff_newstr
2402 |
2403 |.macro ffstring_case, name, lo, hi
2404 | .ffunc_1 name
2405 | ffgccheck
2406 | cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
2407 | mov TMP2, PC // Need another temp register.
2408 | mov STR:RB, [BASE]
2409 | mov RC, STR:RB->len
2410 | mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.b)]
2411 | lea RA, [PC+RC]
2412 | cmp [DISPATCH+DISPATCH_GL(tmpbuf.e)], RA; jb ->fff_fallback_1
2413 | add RB, #STR
2414 |.if X64
2415 | mov TMP3, RC
2416 |.else
2417 | mov ARG3, RC
2418 |.endif
2419 | jmp >3
2420 |1: // ASCII case conversion. Yes, this is suboptimal code (do you care?).
2421 | movzx RA, byte [RB+RC]
2422 | cmp RA, lo
2423 | jb >2
2424 | cmp RA, hi
2425 | ja >2
2426 | xor RA, 0x20
2427 |2:
2428 | mov [PC+RC], RAL
2429 |3:
2430 | sub RC, 1
2431 | jns <1
2432 | mov RD, PC
2433 | mov PC, TMP2
2434 | jmp ->fff_newstr
2435 |.endmacro 2394 |.endmacro
2436 | 2395 |
2437 |ffstring_case string_lower, 0x41, 0x5a 2396 |ffstring_op reverse
2438 |ffstring_case string_upper, 0x61, 0x7a 2397 |ffstring_op lower
2398 |ffstring_op upper
2439 | 2399 |
2440 |//-- Bit library -------------------------------------------------------- 2400 |//-- Bit library --------------------------------------------------------
2441 | 2401 |