diff options
Diffstat (limited to 'src/lj_cdata.c')
-rw-r--r-- | src/lj_cdata.c | 40 |
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. */ | ||
236 | uint64_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 |