diff options
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r-- | src/lj_carith.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c index afe7e682..bb810af8 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c | |||
@@ -11,10 +11,12 @@ | |||
11 | #include "lj_err.h" | 11 | #include "lj_err.h" |
12 | #include "lj_tab.h" | 12 | #include "lj_tab.h" |
13 | #include "lj_meta.h" | 13 | #include "lj_meta.h" |
14 | #include "lj_ir.h" | ||
14 | #include "lj_ctype.h" | 15 | #include "lj_ctype.h" |
15 | #include "lj_cconv.h" | 16 | #include "lj_cconv.h" |
16 | #include "lj_cdata.h" | 17 | #include "lj_cdata.h" |
17 | #include "lj_carith.h" | 18 | #include "lj_carith.h" |
19 | #include "lj_strscan.h" | ||
18 | 20 | ||
19 | /* -- C data arithmetic --------------------------------------------------- */ | 21 | /* -- C data arithmetic --------------------------------------------------- */ |
20 | 22 | ||
@@ -270,6 +272,80 @@ int lj_carith_op(lua_State *L, MMS mm) | |||
270 | return lj_carith_meta(L, cts, &ca, mm); | 272 | return lj_carith_meta(L, cts, &ca, mm); |
271 | } | 273 | } |
272 | 274 | ||
275 | /* -- 64 bit bit operations helpers --------------------------------------- */ | ||
276 | |||
277 | #if LJ_64 | ||
278 | #define B64DEF(name) \ | ||
279 | static LJ_AINLINE uint64_t lj_carith_##name(uint64_t x, int32_t sh) | ||
280 | #else | ||
281 | /* Not inlined on 32 bit archs, since some of these are quite lengthy. */ | ||
282 | #define B64DEF(name) \ | ||
283 | uint64_t LJ_NOINLINE lj_carith_##name(uint64_t x, int32_t sh) | ||
284 | #endif | ||
285 | |||
286 | B64DEF(shl64) { return x << (sh&63); } | ||
287 | B64DEF(shr64) { return x >> (sh&63); } | ||
288 | B64DEF(sar64) { return (uint64_t)((int64_t)x >> (sh&63)); } | ||
289 | B64DEF(rol64) { return lj_rol(x, (sh&63)); } | ||
290 | B64DEF(ror64) { return lj_ror(x, (sh&63)); } | ||
291 | |||
292 | #undef B64DEF | ||
293 | |||
294 | uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op) | ||
295 | { | ||
296 | switch (op) { | ||
297 | case IR_BSHL-IR_BSHL: x = lj_carith_shl64(x, sh); break; | ||
298 | case IR_BSHR-IR_BSHL: x = lj_carith_shr64(x, sh); break; | ||
299 | case IR_BSAR-IR_BSHL: x = lj_carith_sar64(x, sh); break; | ||
300 | case IR_BROL-IR_BSHL: x = lj_carith_rol64(x, sh); break; | ||
301 | case IR_BROR-IR_BSHL: x = lj_carith_ror64(x, sh); break; | ||
302 | default: lua_assert(0); break; | ||
303 | } | ||
304 | return x; | ||
305 | } | ||
306 | |||
307 | /* Equivalent to lj_lib_checkbit(), but handles cdata. */ | ||
308 | uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id) | ||
309 | { | ||
310 | TValue *o = L->base + narg-1; | ||
311 | if (o >= L->top) { | ||
312 | err: | ||
313 | lj_err_argt(L, narg, LUA_TNUMBER); | ||
314 | } else if (LJ_LIKELY(tvisnumber(o))) { | ||
315 | /* Handled below. */ | ||
316 | } else if (tviscdata(o)) { | ||
317 | CTState *cts = ctype_cts(L); | ||
318 | uint8_t *sp = (uint8_t *)cdataptr(cdataV(o)); | ||
319 | CTypeID sid = cdataV(o)->ctypeid; | ||
320 | CType *s = ctype_get(cts, sid); | ||
321 | uint64_t x; | ||
322 | if (ctype_isref(s->info)) { | ||
323 | sp = *(void **)sp; | ||
324 | sid = ctype_cid(s->info); | ||
325 | } | ||
326 | s = ctype_raw(cts, sid); | ||
327 | if (ctype_isenum(s->info)) s = ctype_child(cts, s); | ||
328 | if ((s->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) == | ||
329 | CTINFO(CT_NUM, CTF_UNSIGNED) && s->size == 8) | ||
330 | *id = CTID_UINT64; /* Use uint64_t, since it has the highest rank. */ | ||
331 | else if (!*id) | ||
332 | *id = CTID_INT64; /* Use int64_t, unless already set. */ | ||
333 | lj_cconv_ct_ct(cts, ctype_get(cts, *id), s, | ||
334 | (uint8_t *)&x, sp, CCF_ARG(narg)); | ||
335 | return x; | ||
336 | } else if (!(tvisstr(o) && lj_strscan_number(strV(o), o))) { | ||
337 | goto err; | ||
338 | } | ||
339 | if (LJ_LIKELY(tvisint(o))) { | ||
340 | return (uint32_t)intV(o); | ||
341 | } else { | ||
342 | int32_t i = lj_num2bit(numV(o)); | ||
343 | if (LJ_DUALNUM) setintV(o, i); | ||
344 | return (uint32_t)i; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | |||
273 | /* -- 64 bit integer arithmetic helpers ----------------------------------- */ | 349 | /* -- 64 bit integer arithmetic helpers ----------------------------------- */ |
274 | 350 | ||
275 | #if LJ_32 && LJ_HASJIT | 351 | #if LJ_32 && LJ_HASJIT |