aboutsummaryrefslogtreecommitdiff
path: root/src/lj_cdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_cdata.c')
-rw-r--r--src/lj_cdata.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/lj_cdata.c b/src/lj_cdata.c
index a763908d..499dbc4d 100644
--- a/src/lj_cdata.c
+++ b/src/lj_cdata.c
@@ -230,4 +230,44 @@ void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o, CTInfo qual)
230 lj_cconv_ct_tv(cts, d, dp, o, 0); 230 lj_cconv_ct_tv(cts, d, dp, o, 0);
231} 231}
232 232
233/* -- 64 bit integer arithmetic helpers ----------------------------------- */
234
235/* 64 bit integer x^k. */
236uint64_t lj_cdata_powi64(uint64_t x, uint64_t k, int isunsigned)
237{
238 uint64_t y = 0;
239 int sign = 0;
240 if (k == 0)
241 return 1;
242 if (!isunsigned) {
243 if ((int64_t)k < 0) {
244 if (x == 0)
245 return U64x(7fffffff,ffffffff);
246 else if (x == 1)
247 return 1;
248 else if ((int64_t)x == -1)
249 return (k & 1) ? -1 : 1;
250 else
251 return 0;
252 }
253 if ((int64_t)x < 0) {
254 x = -x;
255 sign = (k & 1);
256 }
257 }
258 for (; (k & 1) == 0; k >>= 1) x *= x;
259 y = x;
260 if ((k >>= 1) != 0) {
261 for (;;) {
262 x *= x;
263 if (k == 1) break;
264 if (k & 1) y *= x;
265 k >>= 1;
266 }
267 y *= x;
268 }
269 if (sign) y = (uint64_t)-(int64_t)y;
270 return y;
271}
272
233#endif 273#endif