diff options
author | Mike Pall <mike> | 2011-01-28 02:15:30 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-01-28 02:15:30 +0100 |
commit | 07d8a53b393b5fbb52f3920f913ab21ce6dde4fa (patch) | |
tree | 0542c4e32ccbad394ba433c06d01df2aaed279e5 /src | |
parent | cd9b8f90e2241c3f6c540844eedc04bc6bc28faf (diff) | |
download | luajit-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.c | 43 | ||||
-rw-r--r-- | src/lj_carith.h | 3 | ||||
-rw-r--r-- | src/lj_crecord.c | 4 | ||||
-rw-r--r-- | src/lj_ir.h | 4 |
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. */ |
229 | uint64_t lj_carith_powi64(uint64_t x, uint64_t k, int isunsigned) | 234 | uint64_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. */ | ||
254 | int64_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 | ||
13 | LJ_FUNC int lj_carith_op(lua_State *L, MMS mm); | 13 | LJ_FUNC int lj_carith_op(lua_State *L, MMS mm); |
14 | 14 | ||
15 | LJ_FUNC uint64_t lj_carith_powi64(uint64_t x, uint64_t k, int isunsigned); | 15 | LJ_FUNC uint64_t lj_carith_powu64(uint64_t x, uint64_t k); |
16 | LJ_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 |