summaryrefslogtreecommitdiff
path: root/src/lj_carith.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r--src/lj_carith.c43
1 files changed, 27 insertions, 16 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