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