aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-03-13 22:44:01 +0100
committerMike Pall <mike>2013-03-14 06:03:18 +0100
commita98aede37772797b4471e1a094452051edff5862 (patch)
tree6e8c86838e359b899ffa0021bf3149087caa71da
parent3e8f5ac7186ecac63e17688b9ba6e72697143dbb (diff)
downloadluajit-a98aede37772797b4471e1a094452051edff5862.tar.gz
luajit-a98aede37772797b4471e1a094452051edff5862.tar.bz2
luajit-a98aede37772797b4471e1a094452051edff5862.zip
FFI: Add 64 bit bitwise operations.
-rw-r--r--doc/ext_ffi_semantics.html17
-rw-r--r--doc/extensions.html3
-rw-r--r--src/Makefile.dep9
-rw-r--r--src/lib_bit.c98
-rw-r--r--src/lj_carith.c76
-rw-r--r--src/lj_carith.h10
-rw-r--r--src/lj_crecord.c95
-rw-r--r--src/lj_crecord.h6
-rw-r--r--src/lj_ffrecord.c66
-rw-r--r--src/lj_ircall.h7
-rw-r--r--src/lj_opt_fold.c41
-rw-r--r--src/lj_opt_split.c127
12 files changed, 495 insertions, 60 deletions
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html
index 03229012..15c9a6db 100644
--- a/doc/ext_ffi_semantics.html
+++ b/doc/ext_ffi_semantics.html
@@ -730,6 +730,22 @@ You'll have to explicitly convert a 64&nbsp;bit integer to a Lua
730number (e.g. for regular floating-point calculations) with 730number (e.g. for regular floating-point calculations) with
731<tt>tonumber()</tt>. But note this may incur a precision loss.</li> 731<tt>tonumber()</tt>. But note this may incur a precision loss.</li>
732 732
733<li><b>64&nbsp;bit bitwise operations</b>: the rules for 64&nbsp;bit
734arithmetic operators apply analogously.<br>
735
736Unlike the other <tt>bit.*</tt> operations, <tt>bit.tobit()</tt>
737converts a cdata number via <tt>int64_t</tt> to <tt>int32_t</tt> and
738returns a Lua number.<br>
739
740For <tt>bit.band()</tt>, <tt>bit.bor()</tt> and <tt>bit.bxor()</tt>, the
741conversion to <tt>int64_t</tt> or <tt>uint64_t</tt> applies to
742<em>all</em> arguments, if <em>any</em> argument is a cdata number.<br>
743
744For all other operations, only the first argument is used to determine
745the output type. This implies that a cdata number as a shift count for
746shifts and rotates is accepted, but that alone does <em>not</em> cause
747a cdata number output.
748
733</ul> 749</ul>
734 750
735<h3 id="cdata_comp">Comparisons of cdata objects</h3> 751<h3 id="cdata_comp">Comparisons of cdata objects</h3>
@@ -1222,7 +1238,6 @@ value.</li>
1222Other missing features: 1238Other missing features:
1223</p> 1239</p>
1224<ul> 1240<ul>
1225<li>Bit operations for 64&nbsp;bit types.</li>
1226<li>Arithmetic for <tt>complex</tt> numbers.</li> 1241<li>Arithmetic for <tt>complex</tt> numbers.</li>
1227<li>Passing structs by value to vararg C&nbsp;functions.</li> 1242<li>Passing structs by value to vararg C&nbsp;functions.</li>
1228<li><a href="extensions.html#exceptions">C++ exception interoperability</a> 1243<li><a href="extensions.html#exceptions">C++ exception interoperability</a>
diff --git a/doc/extensions.html b/doc/extensions.html
index 2bfcc76c..f288fbde 100644
--- a/doc/extensions.html
+++ b/doc/extensions.html
@@ -113,6 +113,9 @@ bit.lshift bit.rshift bit.arshift bit.rol bit.ror bit.bswap
113This module is a LuaJIT built-in &mdash; you don't need to download or 113This module is a LuaJIT built-in &mdash; you don't need to download or
114install Lua BitOp. The Lua BitOp site has full documentation for all 114install Lua BitOp. The Lua BitOp site has full documentation for all
115<a href="http://bitop.luajit.org/api.html"><span class="ext">&raquo;</span>&nbsp;Lua BitOp API functions</a>. 115<a href="http://bitop.luajit.org/api.html"><span class="ext">&raquo;</span>&nbsp;Lua BitOp API functions</a>.
116The FFI adds support for
117<a href="ext_ffi_semantics.html#cdata_arith">64&nbsp;bit bitwise operations<a>,
118using the same API functions.
116</p> 119</p>
117<p> 120<p>
118Please make sure to <tt>require</tt> the module before using any of 121Please make sure to <tt>require</tt> the module before using any of
diff --git a/src/Makefile.dep b/src/Makefile.dep
index f841767b..902d2912 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -7,7 +7,8 @@ lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
7 lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \ 7 lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
8 lj_lib.h lj_libdef.h 8 lj_lib.h lj_libdef.h
9lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ 9lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
10 lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h lj_libdef.h 10 lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_gc.h lj_cdata.h \
11 lj_cconv.h lj_carith.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
11lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ 12lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
12 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \ 13 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \
13 lj_libdef.h 14 lj_libdef.h
@@ -17,7 +18,7 @@ lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
17 lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h 18 lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
18lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h 19lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
19lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ 20lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
20 lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_state.h \ 21 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_state.h \
21 lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h 22 lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
22lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \ 23lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
23 lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \ 24 lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
@@ -58,8 +59,8 @@ lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
58lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 59lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
59 lj_err.h lj_errmsg.h lj_buf.h lj_str.h 60 lj_err.h lj_errmsg.h lj_buf.h lj_str.h
60lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 61lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
61 lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \ 62 lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ir.h lj_ctype.h \
62 lj_cdata.h lj_carith.h 63 lj_cconv.h lj_cdata.h lj_carith.h lj_strscan.h
63lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 64lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
64 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \ 65 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
65 lj_cdata.h lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \ 66 lj_cdata.h lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
diff --git a/src/lib_bit.c b/src/lib_bit.c
index 93fead92..85821b81 100644
--- a/src/lib_bit.c
+++ b/src/lib_bit.c
@@ -13,25 +13,82 @@
13#include "lj_obj.h" 13#include "lj_obj.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_str.h" 15#include "lj_str.h"
16#if LJ_HASFFI
17#include "lj_ctype.h"
18#include "lj_cdata.h"
19#include "lj_cconv.h"
20#include "lj_carith.h"
21#endif
22#include "lj_ff.h"
16#include "lj_lib.h" 23#include "lj_lib.h"
17 24
18/* ------------------------------------------------------------------------ */ 25/* ------------------------------------------------------------------------ */
19 26
20#define LJLIB_MODULE_bit 27#define LJLIB_MODULE_bit
21 28
22LJLIB_ASM(bit_tobit) LJLIB_REC(bit_unary IR_TOBIT) 29#if LJ_HASFFI
30static int bit_result64(lua_State *L, CTypeID id, uint64_t x)
23{ 31{
32 GCcdata *cd = lj_cdata_new_(L, id, 8);
33 *(uint64_t *)cdataptr(cd) = x;
34 setcdataV(L, L->base-1, cd);
35 return FFH_RES(1);
36}
37#endif
38
39LJLIB_ASM(bit_tobit) LJLIB_REC(bit_tobit)
40{
41#if LJ_HASFFI
42 CTypeID id = 0;
43 setintV(L->base-1, (int32_t)lj_carith_check64(L, 1, &id));
44 return FFH_RES(1);
45#else
46 lj_lib_checknumber(L, 1);
47 return FFH_RETRY;
48#endif
49}
50
51LJLIB_ASM(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
52{
53#if LJ_HASFFI
54 CTypeID id = 0;
55 uint64_t x = lj_carith_check64(L, 1, &id);
56 return id ? bit_result64(L, id, ~x) : FFH_RETRY;
57#else
58 lj_lib_checknumber(L, 1);
59 return FFH_RETRY;
60#endif
61}
62
63LJLIB_ASM(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
64{
65#if LJ_HASFFI
66 CTypeID id = 0;
67 uint64_t x = lj_carith_check64(L, 1, &id);
68 return id ? bit_result64(L, id, lj_bswap64(x)) : FFH_RETRY;
69#else
24 lj_lib_checknumber(L, 1); 70 lj_lib_checknumber(L, 1);
25 return FFH_RETRY; 71 return FFH_RETRY;
72#endif
26} 73}
27LJLIB_ASM_(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
28LJLIB_ASM_(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
29 74
30LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL) 75LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
31{ 76{
77#if LJ_HASFFI
78 CTypeID id = 0, id2 = 0;
79 uint64_t x = lj_carith_check64(L, 1, &id);
80 int32_t sh = (int32_t)lj_carith_check64(L, 2, &id2);
81 if (id) {
82 x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
83 return bit_result64(L, id, x);
84 }
85 if (id2) setintV(L->base+1, sh);
86 return FFH_RETRY;
87#else
32 lj_lib_checknumber(L, 1); 88 lj_lib_checknumber(L, 1);
33 lj_lib_checkbit(L, 2); 89 lj_lib_checkbit(L, 2);
34 return FFH_RETRY; 90 return FFH_RETRY;
91#endif
35} 92}
36LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR) 93LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
37LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR) 94LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR)
@@ -40,9 +97,29 @@ LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR)
40 97
41LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND) 98LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
42{ 99{
100#if LJ_HASFFI
101 CTypeID id = 0;
102 TValue *o = L->base, *top = L->top;
103 int i = 0;
104 do { lj_carith_check64(L, ++i, &id); } while (++o < top);
105 if (id) {
106 CTState *cts = ctype_cts(L);
107 CType *ct = ctype_get(cts, id);
108 int op = curr_func(L)->c.ffid - (int)FF_bit_bor;
109 uint64_t x, y = op >= 0 ? 0 : ~(uint64_t)0;
110 o = L->base;
111 do {
112 lj_cconv_ct_tv(cts, ct, (uint8_t *)&x, o, 0);
113 if (op < 0) y &= x; else if (op == 0) y |= x; else y ^= x;
114 } while (++o < top);
115 return bit_result64(L, id, y);
116 }
117 return FFH_RETRY;
118#else
43 int i = 0; 119 int i = 0;
44 do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top); 120 do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
45 return FFH_RETRY; 121 return FFH_RETRY;
122#endif
46} 123}
47LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR) 124LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
48LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR) 125LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
@@ -51,12 +128,21 @@ LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
51 128
52LJLIB_CF(bit_tohex) 129LJLIB_CF(bit_tohex)
53{ 130{
131#if LJ_HASFFI
132 CTypeID id = 0, id2 = 0;
133 uint64_t b = lj_carith_check64(L, 1, &id);
134 int32_t i, dig = id ? 16 : 8;
135 int32_t n = L->base+1>=L->top ? dig : (int32_t)lj_carith_check64(L, 2, &id2);
136 char buf[16];
137#else
54 uint32_t b = (uint32_t)lj_lib_checkbit(L, 1); 138 uint32_t b = (uint32_t)lj_lib_checkbit(L, 1);
55 int32_t i, n = L->base+1 >= L->top ? 8 : lj_lib_checkbit(L, 2); 139 int32_t i, dig = 8;
56 const char *hexdigits = "0123456789abcdef"; 140 int32_t n = L->base+1>=L->top ? dig : lj_lib_checkbit(L, 2);
57 char buf[8]; 141 char buf[8];
142#endif
143 const char *hexdigits = "0123456789abcdef";
58 if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } 144 if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
59 if (n > 8) n = 8; 145 if (n > dig) n = dig;
60 for (i = n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } 146 for (i = n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
61 lua_pushlstring(L, buf, (size_t)n); 147 lua_pushlstring(L, buf, (size_t)n);
62 return 1; 148 return 1;
diff --git a/src/lj_carith.c b/src/lj_carith.c
index 18708d66..9f3208a8 100644
--- a/src/lj_carith.c
+++ b/src/lj_carith.c
@@ -11,10 +11,12 @@
11#include "lj_err.h" 11#include "lj_err.h"
12#include "lj_tab.h" 12#include "lj_tab.h"
13#include "lj_meta.h" 13#include "lj_meta.h"
14#include "lj_ir.h"
14#include "lj_ctype.h" 15#include "lj_ctype.h"
15#include "lj_cconv.h" 16#include "lj_cconv.h"
16#include "lj_cdata.h" 17#include "lj_cdata.h"
17#include "lj_carith.h" 18#include "lj_carith.h"
19#include "lj_strscan.h"
18 20
19/* -- C data arithmetic --------------------------------------------------- */ 21/* -- C data arithmetic --------------------------------------------------- */
20 22
@@ -270,6 +272,80 @@ int lj_carith_op(lua_State *L, MMS mm)
270 return lj_carith_meta(L, cts, &ca, mm); 272 return lj_carith_meta(L, cts, &ca, mm);
271} 273}
272 274
275/* -- 64 bit bit operations helpers --------------------------------------- */
276
277#if LJ_64
278#define B64DEF(name) \
279 static LJ_AINLINE uint64_t lj_carith_##name(uint64_t x, int32_t sh)
280#else
281/* Not inlined on 32 bit archs, since some of these are quite lengthy. */
282#define B64DEF(name) \
283 uint64_t LJ_NOINLINE lj_carith_##name(uint64_t x, int32_t sh)
284#endif
285
286B64DEF(shl64) { return x << (sh&63); }
287B64DEF(shr64) { return x >> (sh&63); }
288B64DEF(sar64) { return (uint64_t)((int64_t)x >> (sh&63)); }
289B64DEF(rol64) { return lj_rol(x, (sh&63)); }
290B64DEF(ror64) { return lj_ror(x, (sh&63)); }
291
292#undef B64DEF
293
294uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op)
295{
296 switch (op) {
297 case IR_BSHL-IR_BSHL: x = lj_carith_shl64(x, sh); break;
298 case IR_BSHR-IR_BSHL: x = lj_carith_shr64(x, sh); break;
299 case IR_BSAR-IR_BSHL: x = lj_carith_sar64(x, sh); break;
300 case IR_BROL-IR_BSHL: x = lj_carith_rol64(x, sh); break;
301 case IR_BROR-IR_BSHL: x = lj_carith_ror64(x, sh); break;
302 default: lua_assert(0); break;
303 }
304 return x;
305}
306
307/* Equivalent to lj_lib_checkbit(), but handles cdata. */
308uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id)
309{
310 TValue *o = L->base + narg-1;
311 if (o >= L->top) {
312 err:
313 lj_err_argt(L, narg, LUA_TNUMBER);
314 } else if (LJ_LIKELY(tvisnumber(o))) {
315 /* Handled below. */
316 } else if (tviscdata(o)) {
317 CTState *cts = ctype_cts(L);
318 uint8_t *sp = (uint8_t *)cdataptr(cdataV(o));
319 CTypeID sid = cdataV(o)->ctypeid;
320 CType *s = ctype_get(cts, sid);
321 uint64_t x;
322 if (ctype_isref(s->info)) {
323 sp = *(void **)sp;
324 sid = ctype_cid(s->info);
325 }
326 s = ctype_raw(cts, sid);
327 if (ctype_isenum(s->info)) s = ctype_child(cts, s);
328 if ((s->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
329 CTINFO(CT_NUM, CTF_UNSIGNED) && s->size == 8)
330 *id = CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
331 else if (!*id)
332 *id = CTID_INT64; /* Use int64_t, unless already set. */
333 lj_cconv_ct_ct(cts, ctype_get(cts, *id), s,
334 (uint8_t *)&x, sp, CCF_ARG(narg));
335 return x;
336 } else if (!(tvisstr(o) && lj_strscan_number(strV(o), o))) {
337 goto err;
338 }
339 if (LJ_LIKELY(tvisint(o))) {
340 return intV(o);
341 } else {
342 int32_t i = lj_num2bit(numV(o));
343 if (LJ_DUALNUM) setintV(o, i);
344 return i;
345 }
346}
347
348
273/* -- 64 bit integer arithmetic helpers ----------------------------------- */ 349/* -- 64 bit integer arithmetic helpers ----------------------------------- */
274 350
275#if LJ_32 && LJ_HASJIT 351#if LJ_32 && LJ_HASJIT
diff --git a/src/lj_carith.h b/src/lj_carith.h
index ae17df00..b1a65d35 100644
--- a/src/lj_carith.h
+++ b/src/lj_carith.h
@@ -12,6 +12,16 @@
12 12
13LJ_FUNC int lj_carith_op(lua_State *L, MMS mm); 13LJ_FUNC int lj_carith_op(lua_State *L, MMS mm);
14 14
15#if LJ_32
16LJ_FUNC uint64_t lj_carith_shl64(uint64_t x, int32_t sh);
17LJ_FUNC uint64_t lj_carith_shr64(uint64_t x, int32_t sh);
18LJ_FUNC uint64_t lj_carith_sar64(uint64_t x, int32_t sh);
19LJ_FUNC uint64_t lj_carith_rol64(uint64_t x, int32_t sh);
20LJ_FUNC uint64_t lj_carith_ror64(uint64_t x, int32_t sh);
21#endif
22LJ_FUNC uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op);
23LJ_FUNC uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id);
24
15#if LJ_32 && LJ_HASJIT 25#if LJ_32 && LJ_HASJIT
16LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k); 26LJ_FUNC int64_t lj_carith_mul64(int64_t x, int64_t k);
17#endif 27#endif
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index a5d896eb..2bf0bc1d 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -1626,6 +1626,101 @@ void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd)
1626 crec_finalizer(J, J->base[0], &rd->argv[1]); 1626 crec_finalizer(J, J->base[0], &rd->argv[1]);
1627} 1627}
1628 1628
1629/* -- 64 bit bit.* library functions -------------------------------------- */
1630
1631/* Determine bit operation type from argument type. */
1632static CTypeID crec_bit64_type(CTState *cts, cTValue *tv)
1633{
1634 if (tviscdata(tv)) {
1635 CType *ct = lj_ctype_rawref(cts, cdataV(tv)->ctypeid);
1636 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1637 if ((ct->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
1638 CTINFO(CT_NUM, CTF_UNSIGNED) && ct->size == 8)
1639 return CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
1640 return CTID_INT64; /* Otherwise use int64_t. */
1641 }
1642 return 0; /* Use regular 32 bit ops. */
1643}
1644
1645void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd)
1646{
1647 CTState *cts = ctype_ctsG(J2G(J));
1648 TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1649 J->base[0], &rd->argv[0]);
1650 if (!tref_isinteger(tr))
1651 tr = emitconv(tr, IRT_INT, tref_type(tr), 0);
1652 J->base[0] = tr;
1653}
1654
1655int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd)
1656{
1657 CTState *cts = ctype_ctsG(J2G(J));
1658 CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1659 if (id) {
1660 TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1661 tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0);
1662 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1663 return 1;
1664 }
1665 return 0;
1666}
1667
1668int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
1669{
1670 CTState *cts = ctype_ctsG(J2G(J));
1671 CTypeID id = 0;
1672 MSize i;
1673 for (i = 0; J->base[i] != 0; i++) {
1674 CTypeID aid = crec_bit64_type(cts, &rd->argv[i]);
1675 if (id < aid) id = aid; /* Determine highest type rank of all arguments. */
1676 }
1677 if (id) {
1678 CType *ct = ctype_get(cts, id);
1679 uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64);
1680 TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]);
1681 for (i = 1; J->base[i] != 0; i++) {
1682 TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]);
1683 tr = emitir(ot, tr, tr2);
1684 }
1685 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1686 return 1;
1687 }
1688 return 0;
1689}
1690
1691int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
1692{
1693 CTState *cts = ctype_ctsG(J2G(J));
1694 CTypeID id;
1695 TRef tsh = 0;
1696 if (J->base[0] && tref_iscdata(J->base[1])) {
1697 tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1698 J->base[1], &rd->argv[1]);
1699 if (!tref_isinteger(tsh))
1700 tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
1701 J->base[1] = tsh;
1702 }
1703 id = crec_bit64_type(cts, &rd->argv[0]);
1704 if (id) {
1705 TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1706 uint32_t op = rd->data;
1707 if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]);
1708 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
1709 !tref_isk(tsh))
1710 tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 63));
1711#ifdef LJ_TARGET_UNIFYROT
1712 if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
1713 op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
1714 tsh = emitir(IRTI(IR_NEG), tsh, tsh);
1715 }
1716#endif
1717 tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh);
1718 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1719 return 1;
1720 }
1721 return 0;
1722}
1723
1629/* -- Miscellaneous library functions ------------------------------------- */ 1724/* -- Miscellaneous library functions ------------------------------------- */
1630 1725
1631void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) 1726void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
diff --git a/src/lj_crecord.h b/src/lj_crecord.h
index dea05f78..92d777b8 100644
--- a/src/lj_crecord.h
+++ b/src/lj_crecord.h
@@ -25,6 +25,12 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd);
25LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd); 25LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd);
26LJ_FUNC void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd); 26LJ_FUNC void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd);
27LJ_FUNC void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd); 27LJ_FUNC void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd);
28
29LJ_FUNC void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd);
30LJ_FUNC int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd);
31LJ_FUNC int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd);
32LJ_FUNC int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd);
33
28LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); 34LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
29#endif 35#endif
30 36
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c
index 730d5c39..4f6aeb37 100644
--- a/src/lj_ffrecord.c
+++ b/src/lj_ffrecord.c
@@ -584,40 +584,66 @@ static void LJ_FASTCALL recff_math_random(jit_State *J, RecordFFData *rd)
584 584
585/* -- Bit library fast functions ------------------------------------------ */ 585/* -- Bit library fast functions ------------------------------------------ */
586 586
587/* Record unary bit.tobit, bit.bnot, bit.bswap. */ 587/* Record bit.tobit. */
588static void LJ_FASTCALL recff_bit_tobit(jit_State *J, RecordFFData *rd)
589{
590 TRef tr = J->base[0];
591#if LJ_HASFFI
592 if (tref_iscdata(tr)) { recff_bit64_tobit(J, rd); return; }
593#endif
594 J->base[0] = lj_opt_narrow_tobit(J, tr);
595 UNUSED(rd);
596}
597
598/* Record unary bit.bnot, bit.bswap. */
588static void LJ_FASTCALL recff_bit_unary(jit_State *J, RecordFFData *rd) 599static void LJ_FASTCALL recff_bit_unary(jit_State *J, RecordFFData *rd)
589{ 600{
590 TRef tr = lj_opt_narrow_tobit(J, J->base[0]); 601#if LJ_HASFFI
591 J->base[0] = (rd->data == IR_TOBIT) ? tr : emitir(IRTI(rd->data), tr, 0); 602 if (recff_bit64_unary(J, rd))
603 return;
604#endif
605 J->base[0] = emitir(IRTI(rd->data), lj_opt_narrow_tobit(J, J->base[0]), 0);
592} 606}
593 607
594/* Record N-ary bit.band, bit.bor, bit.bxor. */ 608/* Record N-ary bit.band, bit.bor, bit.bxor. */
595static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd) 609static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd)
596{ 610{
597 TRef tr = lj_opt_narrow_tobit(J, J->base[0]); 611#if LJ_HASFFI
598 uint32_t op = rd->data; 612 if (recff_bit64_nary(J, rd))
599 BCReg i; 613 return;
600 for (i = 1; J->base[i] != 0; i++) 614#endif
601 tr = emitir(IRTI(op), tr, lj_opt_narrow_tobit(J, J->base[i])); 615 {
602 J->base[0] = tr; 616 TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
617 uint32_t ot = IRTI(rd->data);
618 BCReg i;
619 for (i = 1; J->base[i] != 0; i++)
620 tr = emitir(ot, tr, lj_opt_narrow_tobit(J, J->base[i]));
621 J->base[0] = tr;
622 }
603} 623}
604 624
605/* Record bit shifts. */ 625/* Record bit shifts. */
606static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd) 626static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd)
607{ 627{
608 TRef tr = lj_opt_narrow_tobit(J, J->base[0]); 628#if LJ_HASFFI
609 TRef tsh = lj_opt_narrow_tobit(J, J->base[1]); 629 if (recff_bit64_shift(J, rd))
610 IROp op = (IROp)rd->data; 630 return;
611 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) && 631#endif
612 !tref_isk(tsh)) 632 {
613 tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 31)); 633 TRef tr = lj_opt_narrow_tobit(J, J->base[0]);
634 TRef tsh = lj_opt_narrow_tobit(J, J->base[1]);
635 IROp op = (IROp)rd->data;
636 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
637 !tref_isk(tsh))
638 tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 31));
614#ifdef LJ_TARGET_UNIFYROT 639#ifdef LJ_TARGET_UNIFYROT
615 if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) { 640 if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
616 op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR; 641 op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
617 tsh = emitir(IRTI(IR_NEG), tsh, tsh); 642 tsh = emitir(IRTI(IR_NEG), tsh, tsh);
618 } 643 }
619#endif 644#endif
620 J->base[0] = emitir(IRTI(op), tr, tsh); 645 J->base[0] = emitir(IRTI(op), tr, tsh);
646 }
621} 647}
622 648
623/* -- String library fast functions --------------------------------------- */ 649/* -- String library fast functions --------------------------------------- */
diff --git a/src/lj_ircall.h b/src/lj_ircall.h
index 7fcc532e..2c160bdf 100644
--- a/src/lj_ircall.h
+++ b/src/lj_ircall.h
@@ -172,7 +172,12 @@ typedef struct CCallInfo {
172 _(FFI, memcpy, 3, S, PTR, 0) \ 172 _(FFI, memcpy, 3, S, PTR, 0) \
173 _(FFI, memset, 3, S, PTR, 0) \ 173 _(FFI, memset, 3, S, PTR, 0) \
174 _(FFI, lj_vm_errno, 0, S, INT, CCI_NOFPRCLOBBER) \ 174 _(FFI, lj_vm_errno, 0, S, INT, CCI_NOFPRCLOBBER) \
175 _(FFI32, lj_carith_mul64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) 175 _(FFI32, lj_carith_mul64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \
176 _(FFI32, lj_carith_shl64, 3, N, U64, CCI_NOFPRCLOBBER) \
177 _(FFI32, lj_carith_shr64, 3, N, U64, CCI_NOFPRCLOBBER) \
178 _(FFI32, lj_carith_sar64, 3, N, U64, CCI_NOFPRCLOBBER) \
179 _(FFI32, lj_carith_rol64, 3, N, U64, CCI_NOFPRCLOBBER) \
180 _(FFI32, lj_carith_ror64, 3, N, U64, CCI_NOFPRCLOBBER) \
176 \ 181 \
177 /* End of list. */ 182 /* End of list. */
178 183
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index e67f3ee6..75db47df 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -22,8 +22,8 @@
22#include "lj_trace.h" 22#include "lj_trace.h"
23#if LJ_HASFFI 23#if LJ_HASFFI
24#include "lj_ctype.h" 24#include "lj_ctype.h"
25#endif
26#include "lj_carith.h" 25#include "lj_carith.h"
26#endif
27#include "lj_vm.h" 27#include "lj_vm.h"
28#include "lj_strscan.h" 28#include "lj_strscan.h"
29 29
@@ -336,11 +336,9 @@ LJFOLDF(kfold_intcomp0)
336static uint64_t kfold_int64arith(uint64_t k1, uint64_t k2, IROp op) 336static uint64_t kfold_int64arith(uint64_t k1, uint64_t k2, IROp op)
337{ 337{
338 switch (op) { 338 switch (op) {
339#if LJ_64 || LJ_HASFFI 339#if LJ_HASFFI
340 case IR_ADD: k1 += k2; break; 340 case IR_ADD: k1 += k2; break;
341 case IR_SUB: k1 -= k2; break; 341 case IR_SUB: k1 -= k2; break;
342#endif
343#if LJ_HASFFI
344 case IR_MUL: k1 *= k2; break; 342 case IR_MUL: k1 *= k2; break;
345 case IR_BAND: k1 &= k2; break; 343 case IR_BAND: k1 &= k2; break;
346 case IR_BOR: k1 |= k2; break; 344 case IR_BOR: k1 |= k2; break;
@@ -392,20 +390,10 @@ LJFOLD(BROL KINT64 KINT)
392LJFOLD(BROR KINT64 KINT) 390LJFOLD(BROR KINT64 KINT)
393LJFOLDF(kfold_int64shift) 391LJFOLDF(kfold_int64shift)
394{ 392{
395#if LJ_HASFFI || LJ_64 393#if LJ_HASFFI
396 uint64_t k = ir_k64(fleft)->u64; 394 uint64_t k = ir_k64(fleft)->u64;
397 int32_t sh = (fright->i & 63); 395 int32_t sh = (fright->i & 63);
398 switch ((IROp)fins->o) { 396 return INT64FOLD(lj_carith_shift64(k, sh, fins->o - IR_BSHL));
399 case IR_BSHL: k <<= sh; break;
400#if LJ_HASFFI
401 case IR_BSHR: k >>= sh; break;
402 case IR_BSAR: k = (uint64_t)((int64_t)k >> sh); break;
403 case IR_BROL: k = lj_rol(k, sh); break;
404 case IR_BROR: k = lj_ror(k, sh); break;
405#endif
406 default: lua_assert(0); break;
407 }
408 return INT64FOLD(k);
409#else 397#else
410 UNUSED(J); lua_assert(0); return FAILFOLD; 398 UNUSED(J); lua_assert(0); return FAILFOLD;
411#endif 399#endif
@@ -1192,7 +1180,9 @@ static TRef simplify_intmul_k(jit_State *J, int32_t k)
1192 ** But this is mainly intended for simple address arithmetic. 1180 ** But this is mainly intended for simple address arithmetic.
1193 ** Also it's easier for the backend to optimize the original multiplies. 1181 ** Also it's easier for the backend to optimize the original multiplies.
1194 */ 1182 */
1195 if (k == 1) { /* i * 1 ==> i */ 1183 if (k == 0) { /* i * 0 ==> 0 */
1184 return RIGHTFOLD;
1185 } else if (k == 1) { /* i * 1 ==> i */
1196 return LEFTFOLD; 1186 return LEFTFOLD;
1197 } else if ((k & (k-1)) == 0) { /* i * 2^k ==> i << k */ 1187 } else if ((k & (k-1)) == 0) { /* i * 2^k ==> i << k */
1198 fins->o = IR_BSHL; 1188 fins->o = IR_BSHL;
@@ -1205,9 +1195,7 @@ static TRef simplify_intmul_k(jit_State *J, int32_t k)
1205LJFOLD(MUL any KINT) 1195LJFOLD(MUL any KINT)
1206LJFOLDF(simplify_intmul_k32) 1196LJFOLDF(simplify_intmul_k32)
1207{ 1197{
1208 if (fright->i == 0) /* i * 0 ==> 0 */ 1198 if (fright->i >= 0)
1209 return INTFOLD(0);
1210 else if (fright->i > 0)
1211 return simplify_intmul_k(J, fright->i); 1199 return simplify_intmul_k(J, fright->i);
1212 return NEXTFOLD; 1200 return NEXTFOLD;
1213} 1201}
@@ -1215,14 +1203,13 @@ LJFOLDF(simplify_intmul_k32)
1215LJFOLD(MUL any KINT64) 1203LJFOLD(MUL any KINT64)
1216LJFOLDF(simplify_intmul_k64) 1204LJFOLDF(simplify_intmul_k64)
1217{ 1205{
1218 if (ir_kint64(fright)->u64 == 0) /* i * 0 ==> 0 */ 1206#if LJ_HASFFI
1219 return INT64FOLD(0); 1207 if (ir_kint64(fright)->u64 < 0x80000000u)
1220#if LJ_64
1221 /* NYI: SPLIT for BSHL and 32 bit backend support. */
1222 else if (ir_kint64(fright)->u64 < 0x80000000u)
1223 return simplify_intmul_k(J, (int32_t)ir_kint64(fright)->u64); 1208 return simplify_intmul_k(J, (int32_t)ir_kint64(fright)->u64);
1224#endif
1225 return NEXTFOLD; 1209 return NEXTFOLD;
1210#else
1211 UNUSED(J); lua_assert(0); return FAILFOLD;
1212#endif
1226} 1213}
1227 1214
1228LJFOLD(MOD any KINT) 1215LJFOLD(MOD any KINT)
@@ -1522,7 +1509,7 @@ LJFOLD(BOR BOR KINT64)
1522LJFOLD(BXOR BXOR KINT64) 1509LJFOLD(BXOR BXOR KINT64)
1523LJFOLDF(reassoc_intarith_k64) 1510LJFOLDF(reassoc_intarith_k64)
1524{ 1511{
1525#if LJ_HASFFI || LJ_64 1512#if LJ_HASFFI
1526 IRIns *irk = IR(fleft->op2); 1513 IRIns *irk = IR(fleft->op2);
1527 if (irk->o == IR_KINT64) { 1514 if (irk->o == IR_KINT64) {
1528 uint64_t k = kfold_int64arith(ir_k64(irk)->u64, 1515 uint64_t k = kfold_int64arith(ir_k64(irk)->u64,
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c
index 2b04e77d..a0526c9d 100644
--- a/src/lj_opt_split.c
+++ b/src/lj_opt_split.c
@@ -140,6 +140,7 @@ static IRRef split_call_l(jit_State *J, IRRef1 *hisubst, IRIns *oir,
140 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id); 140 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id);
141 return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp); 141 return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
142} 142}
143#endif
143 144
144/* Emit a CALLN with one split 64 bit argument and a 32 bit argument. */ 145/* Emit a CALLN with one split 64 bit argument and a 32 bit argument. */
145static IRRef split_call_li(jit_State *J, IRRef1 *hisubst, IRIns *oir, 146static IRRef split_call_li(jit_State *J, IRRef1 *hisubst, IRIns *oir,
@@ -156,7 +157,6 @@ static IRRef split_call_li(jit_State *J, IRRef1 *hisubst, IRIns *oir,
156 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id); 157 ir->prev = tmp = split_emit(J, IRTI(IR_CALLN), tmp, id);
157 return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp); 158 return split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
158} 159}
159#endif
160 160
161/* Emit a CALLN with two split 64 bit arguments. */ 161/* Emit a CALLN with two split 64 bit arguments. */
162static IRRef split_call_ll(jit_State *J, IRRef1 *hisubst, IRIns *oir, 162static IRRef split_call_ll(jit_State *J, IRRef1 *hisubst, IRIns *oir,
@@ -196,6 +196,118 @@ static IRRef split_ptr(jit_State *J, IRIns *oir, IRRef ref)
196 return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs)); 196 return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs));
197} 197}
198 198
199#if LJ_HASFFI
200static IRRef split_bitshift(jit_State *J, IRRef1 *hisubst,
201 IRIns *oir, IRIns *nir, IRIns *ir)
202{
203 IROp op = ir->o;
204 IRRef kref = nir->op2;
205 if (irref_isk(kref)) { /* Optimize constant shifts. */
206 int32_t k = (IR(kref)->i & 63);
207 IRRef lo = nir->op1, hi = hisubst[ir->op1];
208 if (op == IR_BROL || op == IR_BROR) {
209 if (op == IR_BROR) k = (-k & 63);
210 if (k >= 32) { IRRef t = lo; lo = hi; hi = t; k -= 32; }
211 if (k == 0) {
212 passthrough:
213 J->cur.nins--;
214 ir->prev = lo;
215 return hi;
216 } else {
217 TRef k1, k2;
218 IRRef t1, t2, t3, t4;
219 J->cur.nins--;
220 k1 = lj_ir_kint(J, k);
221 k2 = lj_ir_kint(J, (-k & 31));
222 t1 = split_emit(J, IRTI(IR_BSHL), lo, k1);
223 t2 = split_emit(J, IRTI(IR_BSHL), hi, k1);
224 t3 = split_emit(J, IRTI(IR_BSHR), lo, k2);
225 t4 = split_emit(J, IRTI(IR_BSHR), hi, k2);
226 ir->prev = split_emit(J, IRTI(IR_BOR), t1, t4);
227 return split_emit(J, IRTI(IR_BOR), t2, t3);
228 }
229 } else if (k == 0) {
230 goto passthrough;
231 } else if (k < 32) {
232 if (op == IR_BSHL) {
233 IRRef t1 = split_emit(J, IRTI(IR_BSHL), hi, kref);
234 IRRef t2 = split_emit(J, IRTI(IR_BSHR), lo, lj_ir_kint(J, (-k&31)));
235 return split_emit(J, IRTI(IR_BOR), t1, t2);
236 } else {
237 IRRef t1 = ir->prev, t2;
238 lua_assert(op == IR_BSHR || op == IR_BSAR);
239 nir->o = IR_BSHR;
240 t2 = split_emit(J, IRTI(IR_BSHL), hi, lj_ir_kint(J, (-k&31)));
241 ir->prev = split_emit(J, IRTI(IR_BOR), t1, t2);
242 return split_emit(J, IRTI(op), hi, kref);
243 }
244 } else {
245 if (op == IR_BSHL) {
246 if (k == 32)
247 J->cur.nins--;
248 else
249 lo = ir->prev;
250 ir->prev = lj_ir_kint(J, 0);
251 return lo;
252 } else {
253 lua_assert(op == IR_BSHR || op == IR_BSAR);
254 if (k == 32) {
255 J->cur.nins--;
256 ir->prev = hi;
257 } else {
258 nir->op1 = hi;
259 }
260 if (op == IR_BSHR)
261 return lj_ir_kint(J, 0);
262 else
263 return split_emit(J, IRTI(IR_BSAR), hi, lj_ir_kint(J, 31));
264 }
265 }
266 }
267 return split_call_li(J, hisubst, oir, ir,
268 op - IR_BSHL + IRCALL_lj_carith_shl64);
269}
270
271static IRRef split_bitop(jit_State *J, IRRef1 *hisubst,
272 IRIns *nir, IRIns *ir)
273{
274 IROp op = ir->o;
275 IRRef hi, kref = nir->op2;
276 if (irref_isk(kref)) { /* Optimize bit operations with lo constant. */
277 int32_t k = IR(kref)->i;
278 if (k == 0 || k == -1) {
279 if (op == IR_BAND) k = ~k;
280 if (k == 0) {
281 J->cur.nins--;
282 ir->prev = nir->op1;
283 } else if (op == IR_BXOR) {
284 nir->o = IR_BNOT;
285 nir->op2 = 0;
286 } else {
287 J->cur.nins--;
288 ir->prev = kref;
289 }
290 }
291 }
292 hi = hisubst[ir->op1];
293 kref = hisubst[ir->op2];
294 if (irref_isk(kref)) { /* Optimize bit operations with hi constant. */
295 int32_t k = IR(kref)->i;
296 if (k == 0 || k == -1) {
297 if (op == IR_BAND) k = ~k;
298 if (k == 0) {
299 return hi;
300 } else if (op == IR_BXOR) {
301 return split_emit(J, IRTI(IR_BNOT), hi, 0);
302 } else {
303 return kref;
304 }
305 }
306 }
307 return split_emit(J, IRTI(op), hi, kref);
308}
309#endif
310
199/* Transform the old IR to the new IR. */ 311/* Transform the old IR to the new IR. */
200static void split_ir(jit_State *J) 312static void split_ir(jit_State *J)
201{ 313{
@@ -417,6 +529,19 @@ static void split_ir(jit_State *J)
417 irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 : 529 irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
418 IRCALL_lj_carith_powu64); 530 IRCALL_lj_carith_powu64);
419 break; 531 break;
532 case IR_BNOT:
533 hi = split_emit(J, IRTI(IR_BNOT), hiref, 0);
534 break;
535 case IR_BSWAP:
536 ir->prev = split_emit(J, IRTI(IR_BSWAP), hiref, 0);
537 hi = nref;
538 break;
539 case IR_BAND: case IR_BOR: case IR_BXOR:
540 hi = split_bitop(J, hisubst, nir, ir);
541 break;
542 case IR_BSHL: case IR_BSHR: case IR_BSAR: case IR_BROL: case IR_BROR:
543 hi = split_bitshift(J, hisubst, oir, nir, ir);
544 break;
420 case IR_FLOAD: 545 case IR_FLOAD:
421 lua_assert(ir->op2 == IRFL_CDATA_INT64); 546 lua_assert(ir->op2 == IRFL_CDATA_INT64);
422 hi = split_emit(J, IRTI(IR_FLOAD), nir->op1, IRFL_CDATA_INT64_4); 547 hi = split_emit(J, IRTI(IR_FLOAD), nir->op1, IRFL_CDATA_INT64_4);