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 | |
| 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.
| -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 |
