aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-28 02:15:30 +0100
committerMike Pall <mike>2011-01-28 02:15:30 +0100
commit07d8a53b393b5fbb52f3920f913ab21ce6dde4fa (patch)
tree0542c4e32ccbad394ba433c06d01df2aaed279e5 /src
parentcd9b8f90e2241c3f6c540844eedc04bc6bc28faf (diff)
downloadluajit-07d8a53b393b5fbb52f3920f913ab21ce6dde4fa.tar.gz
luajit-07d8a53b393b5fbb52f3920f913ab21ce6dde4fa.tar.bz2
luajit-07d8a53b393b5fbb52f3920f913ab21ce6dde4fa.zip
FFI: Split up 64 bit x^k helper into signed/unsigned.
Diffstat (limited to 'src')
-rw-r--r--src/lj_carith.c43
-rw-r--r--src/lj_carith.h3
-rw-r--r--src/lj_crecord.c4
-rw-r--r--src/lj_ir.h4
4 files changed, 34 insertions, 20 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c
index a7d92983..46f07be7 100644
--- a/src/lj_carith.c
+++ b/src/lj_carith.c
@@ -184,7 +184,12 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
184 else 184 else
185 *up = u0 % u1; 185 *up = u0 % u1;
186 break; 186 break;
187 case MM_pow: *up = lj_carith_powi64(u0, u1, (id == CTID_UINT64)); break; 187 case MM_pow:
188 if (id == CTID_INT64)
189 *up = (uint64_t)lj_carith_powi64((int64_t)u0, (int64_t)u1);
190 else
191 *up = lj_carith_powu64(u0, u1);
192 break;
188 case MM_unm: *up = (uint64_t)-(int64_t)u0; break; 193 case MM_unm: *up = (uint64_t)-(int64_t)u0; break;
189 default: lua_assert(0); break; 194 default: lua_assert(0); break;
190 } 195 }
@@ -225,24 +230,12 @@ int lj_carith_op(lua_State *L, MMS mm)
225 230
226/* -- 64 bit integer arithmetic helpers ----------------------------------- */ 231/* -- 64 bit integer arithmetic helpers ----------------------------------- */
227 232
228/* 64 bit integer x^k. */ 233/* Unsigned 64 bit x^k. */
229uint64_t lj_carith_powi64(uint64_t x, uint64_t k, int isunsigned) 234uint64_t lj_carith_powu64(uint64_t x, uint64_t k)
230{ 235{
231 uint64_t y = 0; 236 uint64_t y;
232 if (k == 0) 237 if (k == 0)
233 return 1; 238 return 1;
234 if (!isunsigned) {
235 if ((int64_t)k < 0) {
236 if (x == 0)
237 return U64x(7fffffff,ffffffff);
238 else if (x == 1)
239 return 1;
240 else if ((int64_t)x == -1)
241 return (k & 1) ? -1 : 1;
242 else
243 return 0;
244 }
245 }
246 for (; (k & 1) == 0; k >>= 1) x *= x; 239 for (; (k & 1) == 0; k >>= 1) x *= x;
247 y = x; 240 y = x;
248 if ((k >>= 1) != 0) { 241 if ((k >>= 1) != 0) {
@@ -257,4 +250,22 @@ uint64_t lj_carith_powi64(uint64_t x, uint64_t k, int isunsigned)
257 return y; 250 return y;
258} 251}
259 252
253/* Signed 64 bit x^k. */
254int64_t lj_carith_powi64(int64_t x, int64_t k)
255{
256 if (k == 0)
257 return 1;
258 if (k < 0) {
259 if (x == 0)
260 return U64x(7fffffff,ffffffff);
261 else if (x == 1)
262 return 1;
263 else if (x == -1)
264 return (k & 1) ? -1 : 1;
265 else
266 return 0;
267 }
268 return (int64_t)lj_carith_powu64((uint64_t)x, (uint64_t)k);
269}
270
260#endif 271#endif
diff --git a/src/lj_carith.h b/src/lj_carith.h
index acb095db..6870172b 100644
--- a/src/lj_carith.h
+++ b/src/lj_carith.h
@@ -12,7 +12,8 @@
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
15LJ_FUNC uint64_t lj_carith_powi64(uint64_t x, uint64_t k, int isunsigned); 15LJ_FUNC uint64_t lj_carith_powu64(uint64_t x, uint64_t k);
16LJ_FUNC int64_t lj_carith_powi64(int64_t x, int64_t k);
16 17
17#endif 18#endif
18 19
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 647c464a..86e95679 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -689,8 +689,8 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
689 J->postproc = LJ_POST_FIXGUARD; 689 J->postproc = LJ_POST_FIXGUARD;
690 return TREF_TRUE; 690 return TREF_TRUE;
691 } else if (mm == MM_pow) { 691 } else if (mm == MM_pow) {
692 tr = lj_ir_call(J, IRCALL_lj_carith_powi64, sp[0], sp[1], 692 tr = lj_ir_call(J, dt == IRT_I64 ? IRCALL_lj_carith_powi64 :
693 lj_ir_kint(J, (int)dt-(int)IRT_I64)); 693 IRCALL_lj_carith_powu64, sp[0], sp[1]);
694 } else { 694 } else {
695 if (mm == MM_div || mm == MM_mod) 695 if (mm == MM_div || mm == MM_mod)
696 return 0; /* NYI: integer div, mod. */ 696 return 0; /* NYI: integer div, mod. */
diff --git a/src/lj_ir.h b/src/lj_ir.h
index 6dee36c6..1cb3566e 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -251,11 +251,13 @@ typedef struct CCallInfo {
251#define CCI_CASTU64 0x0200 /* Cast u64 result to number. */ 251#define CCI_CASTU64 0x0200 /* Cast u64 result to number. */
252#define CCI_NOFPRCLOBBER 0x0400 /* Does not clobber any FPRs. */ 252#define CCI_NOFPRCLOBBER 0x0400 /* Does not clobber any FPRs. */
253#define CCI_FASTCALL 0x0800 /* Fastcall convention. */ 253#define CCI_FASTCALL 0x0800 /* Fastcall convention. */
254#define CCI_STACK64 0x1000 /* Needs 64 bits per argument. */
254 255
255/* Function definitions for CALL* instructions. */ 256/* Function definitions for CALL* instructions. */
256#if LJ_HASFFI 257#if LJ_HASFFI
257#define IRCALLDEF_FFI(_) \ 258#define IRCALLDEF_FFI(_) \
258 _(lj_carith_powi64, 3, N, U64, CCI_NOFPRCLOBBER) 259 _(lj_carith_powi64, 2, N, I64, CCI_STACK64|CCI_NOFPRCLOBBER) \
260 _(lj_carith_powu64, 2, N, U64, CCI_STACK64|CCI_NOFPRCLOBBER)
259#else 261#else
260#define IRCALLDEF_FFI(_) 262#define IRCALLDEF_FFI(_)
261#endif 263#endif