aboutsummaryrefslogtreecommitdiff
path: root/src/lj_carith.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r--src/lj_carith.c83
1 files changed, 81 insertions, 2 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c
index 462dbae4..1a2a058f 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
@@ -120,7 +122,7 @@ static int carith_ptr(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
120 setboolV(L->top-1, ((uintptr_t)pp < (uintptr_t)pp2)); 122 setboolV(L->top-1, ((uintptr_t)pp < (uintptr_t)pp2));
121 return 1; 123 return 1;
122 } else { 124 } else {
123 lua_assert(mm == MM_le); 125 lj_assertL(mm == MM_le, "bad metamethod %d", mm);
124 setboolV(L->top-1, ((uintptr_t)pp <= (uintptr_t)pp2)); 126 setboolV(L->top-1, ((uintptr_t)pp <= (uintptr_t)pp2));
125 return 1; 127 return 1;
126 } 128 }
@@ -206,7 +208,9 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
206 *up = lj_carith_powu64(u0, u1); 208 *up = lj_carith_powu64(u0, u1);
207 break; 209 break;
208 case MM_unm: *up = (uint64_t)-(int64_t)u0; break; 210 case MM_unm: *up = (uint64_t)-(int64_t)u0; break;
209 default: lua_assert(0); break; 211 default:
212 lj_assertL(0, "bad metamethod %d", mm);
213 break;
210 } 214 }
211 lj_gc_check(L); 215 lj_gc_check(L);
212 return 1; 216 return 1;
@@ -272,6 +276,81 @@ int lj_carith_op(lua_State *L, MMS mm)
272 return lj_carith_meta(L, cts, &ca, mm); 276 return lj_carith_meta(L, cts, &ca, mm);
273} 277}
274 278
279/* -- 64 bit bit operations helpers --------------------------------------- */
280
281#if LJ_64
282#define B64DEF(name) \
283 static LJ_AINLINE uint64_t lj_carith_##name(uint64_t x, int32_t sh)
284#else
285/* Not inlined on 32 bit archs, since some of these are quite lengthy. */
286#define B64DEF(name) \
287 uint64_t LJ_NOINLINE lj_carith_##name(uint64_t x, int32_t sh)
288#endif
289
290B64DEF(shl64) { return x << (sh&63); }
291B64DEF(shr64) { return x >> (sh&63); }
292B64DEF(sar64) { return (uint64_t)((int64_t)x >> (sh&63)); }
293B64DEF(rol64) { return lj_rol(x, (sh&63)); }
294B64DEF(ror64) { return lj_ror(x, (sh&63)); }
295
296#undef B64DEF
297
298uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op)
299{
300 switch (op) {
301 case IR_BSHL-IR_BSHL: x = lj_carith_shl64(x, sh); break;
302 case IR_BSHR-IR_BSHL: x = lj_carith_shr64(x, sh); break;
303 case IR_BSAR-IR_BSHL: x = lj_carith_sar64(x, sh); break;
304 case IR_BROL-IR_BSHL: x = lj_carith_rol64(x, sh); break;
305 case IR_BROR-IR_BSHL: x = lj_carith_ror64(x, sh); break;
306 default:
307 lj_assertX(0, "bad shift op %d", op);
308 break;
309 }
310 return x;
311}
312
313/* Equivalent to lj_lib_checkbit(), but handles cdata. */
314uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id)
315{
316 TValue *o = L->base + narg-1;
317 if (o >= L->top) {
318 err:
319 lj_err_argt(L, narg, LUA_TNUMBER);
320 } else if (LJ_LIKELY(tvisnumber(o))) {
321 /* Handled below. */
322 } else if (tviscdata(o)) {
323 CTState *cts = ctype_cts(L);
324 uint8_t *sp = (uint8_t *)cdataptr(cdataV(o));
325 CTypeID sid = cdataV(o)->ctypeid;
326 CType *s = ctype_get(cts, sid);
327 uint64_t x;
328 if (ctype_isref(s->info)) {
329 sp = *(void **)sp;
330 sid = ctype_cid(s->info);
331 }
332 s = ctype_raw(cts, sid);
333 if (ctype_isenum(s->info)) s = ctype_child(cts, s);
334 if ((s->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
335 CTINFO(CT_NUM, CTF_UNSIGNED) && s->size == 8)
336 *id = CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
337 else if (!*id)
338 *id = CTID_INT64; /* Use int64_t, unless already set. */
339 lj_cconv_ct_ct(cts, ctype_get(cts, *id), s,
340 (uint8_t *)&x, sp, CCF_ARG(narg));
341 return x;
342 } else if (!(tvisstr(o) && lj_strscan_number(strV(o), o))) {
343 goto err;
344 }
345 if (LJ_LIKELY(tvisint(o))) {
346 return (uint32_t)intV(o);
347 } else {
348 int32_t i = lj_num2bit(numV(o));
349 if (LJ_DUALNUM) setintV(o, i);
350 return (uint32_t)i;
351 }
352}
353
275/* -- 64 bit integer arithmetic helpers ----------------------------------- */ 354/* -- 64 bit integer arithmetic helpers ----------------------------------- */
276 355
277#if LJ_32 && LJ_HASJIT 356#if LJ_32 && LJ_HASJIT