3 ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
18 #include "lj_carith.h"
19 #include "lj_strscan.h"
21 /* -- C data arithmetic --------------------------------------------------- */
23 /* Binary operands of an operator converted to ctypes. */
24 typedef struct CDArith
{
29 /* Check arguments for arithmetic metamethods. */
30 static int carith_checkarg(lua_State
*L
, CTState
*cts
, CDArith
*ca
)
36 lj_err_argt(L
, 1, LUA_TCDATA
);
37 for (i
= 0; i
< 2; i
++, o
++) {
39 GCcdata
*cd
= cdataV(o
);
40 CTypeID id
= (CTypeID
)cd
->ctypeid
;
41 CType
*ct
= ctype_raw(cts
, id
);
42 uint8_t *p
= (uint8_t *)cdataptr(cd
);
43 if (ctype_isptr(ct
->info
)) {
44 p
= (uint8_t *)cdata_getptr(p
, ct
->size
);
45 if (ctype_isref(ct
->info
)) ct
= ctype_rawchild(cts
, ct
);
46 } else if (ctype_isfunc(ct
->info
)) {
47 p
= (uint8_t *)*(void **)p
;
49 lj_ctype_intern(cts
, CTINFO(CT_PTR
, CTALIGN_PTR
|id
), CTSIZE_PTR
));
51 if (ctype_isenum(ct
->info
)) ct
= ctype_child(cts
, ct
);
54 } else if (tvisint(o
)) {
55 ca
->ct
[i
] = ctype_get(cts
, CTID_INT32
);
56 ca
->p
[i
] = (uint8_t *)&o
->i
;
57 } else if (tvisnum(o
)) {
58 ca
->ct
[i
] = ctype_get(cts
, CTID_DOUBLE
);
59 ca
->p
[i
] = (uint8_t *)&o
->n
;
60 } else if (tvisnil(o
)) {
61 ca
->ct
[i
] = ctype_get(cts
, CTID_P_VOID
);
62 ca
->p
[i
] = (uint8_t *)0;
63 } else if (tvisstr(o
)) {
64 TValue
*o2
= i
== 0 ? o
+1 : o
-1;
65 CType
*ct
= ctype_raw(cts
, cdataV(o2
)->ctypeid
);
67 ca
->p
[i
] = (uint8_t *)strVdata(o
);
69 if (ctype_isenum(ct
->info
)) {
71 CType
*cct
= lj_ctype_getfield(cts
, ct
, strV(o
), &ofs
);
72 if (cct
&& ctype_isconstval(cct
->info
)) {
73 ca
->ct
[i
] = ctype_child(cts
, cct
);
74 ca
->p
[i
] = (uint8_t *)&cct
->size
; /* Assumes ct does not grow. */
77 ca
->ct
[1-i
] = ct
; /* Use enum to improve error message. */
84 ca
->p
[i
] = (void *)(intptr_t)1; /* To make it unequal. */
91 /* Pointer arithmetic. */
92 static int carith_ptr(lua_State
*L
, CTState
*cts
, CDArith
*ca
, MMS mm
)
94 CType
*ctp
= ca
->ct
[0];
95 uint8_t *pp
= ca
->p
[0];
100 if (ctype_isptr(ctp
->info
) || ctype_isrefarray(ctp
->info
)) {
101 if ((mm
== MM_sub
|| mm
== MM_eq
|| mm
== MM_lt
|| mm
== MM_le
) &&
102 (ctype_isptr(ca
->ct
[1]->info
) || ctype_isrefarray(ca
->ct
[1]->info
))) {
103 uint8_t *pp2
= ca
->p
[1];
104 if (mm
== MM_eq
) { /* Pointer equality. Incompatible pointers are ok. */
105 setboolV(L
->top
-1, (pp
== pp2
));
108 if (!lj_cconv_compatptr(cts
, ctp
, ca
->ct
[1], CCF_IGNQUAL
))
110 if (mm
== MM_sub
) { /* Pointer difference. */
112 sz
= lj_ctype_size(cts
, ctype_cid(ctp
->info
)); /* Element size. */
113 if (sz
== 0 || sz
== CTSIZE_INVALID
)
115 diff
= ((intptr_t)pp
- (intptr_t)pp2
) / (int32_t)sz
;
116 /* All valid pointer differences on x64 are in (-2^47, +2^47),
117 ** which fits into a double without loss of precision.
119 setintptrV(L
->top
-1, (int32_t)diff
);
121 } else if (mm
== MM_lt
) { /* Pointer comparison (unsigned). */
122 setboolV(L
->top
-1, ((uintptr_t)pp
< (uintptr_t)pp2
));
125 lua_assert(mm
== MM_le
);
126 setboolV(L
->top
-1, ((uintptr_t)pp
<= (uintptr_t)pp2
));
130 if (!((mm
== MM_add
|| mm
== MM_sub
) && ctype_isnum(ca
->ct
[1]->info
)))
132 lj_cconv_ct_ct(cts
, ctype_get(cts
, CTID_INT_PSZ
), ca
->ct
[1],
133 (uint8_t *)&idx
, ca
->p
[1], 0);
134 if (mm
== MM_sub
) idx
= -idx
;
135 } else if (mm
== MM_add
&& ctype_isnum(ctp
->info
) &&
136 (ctype_isptr(ca
->ct
[1]->info
) || ctype_isrefarray(ca
->ct
[1]->info
))) {
137 /* Swap pointer and index. */
138 ctp
= ca
->ct
[1]; pp
= ca
->p
[1];
139 lj_cconv_ct_ct(cts
, ctype_get(cts
, CTID_INT_PSZ
), ca
->ct
[0],
140 (uint8_t *)&idx
, ca
->p
[0], 0);
144 sz
= lj_ctype_size(cts
, ctype_cid(ctp
->info
)); /* Element size. */
145 if (sz
== CTSIZE_INVALID
)
147 pp
+= idx
*(int32_t)sz
; /* Compute pointer + index. */
148 id
= lj_ctype_intern(cts
, CTINFO(CT_PTR
, CTALIGN_PTR
|ctype_cid(ctp
->info
)),
150 cd
= lj_cdata_new(cts
, id
, CTSIZE_PTR
);
151 *(uint8_t **)cdataptr(cd
) = pp
;
152 setcdataV(L
, L
->top
-1, cd
);
157 /* 64 bit integer arithmetic. */
158 static int carith_int64(lua_State
*L
, CTState
*cts
, CDArith
*ca
, MMS mm
)
160 if (ctype_isnum(ca
->ct
[0]->info
) && ca
->ct
[0]->size
<= 8 &&
161 ctype_isnum(ca
->ct
[1]->info
) && ca
->ct
[1]->size
<= 8) {
162 CTypeID id
= (((ca
->ct
[0]->info
& CTF_UNSIGNED
) && ca
->ct
[0]->size
== 8) ||
163 ((ca
->ct
[1]->info
& CTF_UNSIGNED
) && ca
->ct
[1]->size
== 8)) ?
164 CTID_UINT64
: CTID_INT64
;
165 CType
*ct
= ctype_get(cts
, id
);
167 uint64_t u0
, u1
, *up
;
168 lj_cconv_ct_ct(cts
, ct
, ca
->ct
[0], (uint8_t *)&u0
, ca
->p
[0], 0);
170 lj_cconv_ct_ct(cts
, ct
, ca
->ct
[1], (uint8_t *)&u1
, ca
->p
[1], 0);
173 setboolV(L
->top
-1, (u0
== u1
));
177 id
== CTID_INT64
? ((int64_t)u0
< (int64_t)u1
) : (u0
< u1
));
181 id
== CTID_INT64
? ((int64_t)u0
<= (int64_t)u1
) : (u0
<= u1
));
185 cd
= lj_cdata_new(cts
, id
, 8);
186 up
= (uint64_t *)cdataptr(cd
);
187 setcdataV(L
, L
->top
-1, cd
);
189 case MM_add
: *up
= u0
+ u1
; break;
190 case MM_sub
: *up
= u0
- u1
; break;
191 case MM_mul
: *up
= u0
* u1
; break;
193 if (id
== CTID_INT64
)
194 *up
= (uint64_t)lj_carith_divi64((int64_t)u0
, (int64_t)u1
);
196 *up
= lj_carith_divu64(u0
, u1
);
199 if (id
== CTID_INT64
)
200 *up
= (uint64_t)lj_carith_modi64((int64_t)u0
, (int64_t)u1
);
202 *up
= lj_carith_modu64(u0
, u1
);
205 if (id
== CTID_INT64
)
206 *up
= (uint64_t)lj_carith_powi64((int64_t)u0
, (int64_t)u1
);
208 *up
= lj_carith_powu64(u0
, u1
);
210 case MM_unm
: *up
= (uint64_t)-(int64_t)u0
; break;
211 default: lua_assert(0); break;
219 /* Handle ctype arithmetic metamethods. */
220 static int lj_carith_meta(lua_State
*L
, CTState
*cts
, CDArith
*ca
, MMS mm
)
223 if (tviscdata(L
->base
)) {
224 CTypeID id
= cdataV(L
->base
)->ctypeid
;
225 CType
*ct
= ctype_raw(cts
, id
);
226 if (ctype_isptr(ct
->info
)) id
= ctype_cid(ct
->info
);
227 tv
= lj_ctype_meta(cts
, id
, mm
);
229 if (!tv
&& L
->base
+1 < L
->top
&& tviscdata(L
->base
+1)) {
230 CTypeID id
= cdataV(L
->base
+1)->ctypeid
;
231 CType
*ct
= ctype_raw(cts
, id
);
232 if (ctype_isptr(ct
->info
)) id
= ctype_cid(ct
->info
);
233 tv
= lj_ctype_meta(cts
, id
, mm
);
237 int i
, isenum
= -1, isstr
= -1;
238 if (mm
== MM_eq
) { /* Equality checks never raise an error. */
239 int eq
= ca
->p
[0] == ca
->p
[1];
240 setboolV(L
->top
-1, eq
);
241 setboolV(&G(L
)->tmptv2
, eq
); /* Remember for trace recorder. */
244 for (i
= 0; i
< 2; i
++) {
245 if (ca
->ct
[i
] && tviscdata(L
->base
+i
)) {
246 if (ctype_isenum(ca
->ct
[i
]->info
)) isenum
= i
;
247 repr
[i
] = strdata(lj_ctype_repr(L
, ctype_typeid(cts
, ca
->ct
[i
]), NULL
));
249 if (tvisstr(&L
->base
[i
])) isstr
= i
;
250 repr
[i
] = lj_typename(&L
->base
[i
]);
253 if ((isenum
^ isstr
) == 1)
254 lj_err_callerv(L
, LJ_ERR_FFI_BADCONV
, repr
[isstr
], repr
[isenum
]);
255 lj_err_callerv(L
, mm
== MM_len
? LJ_ERR_FFI_BADLEN
:
256 mm
== MM_concat
? LJ_ERR_FFI_BADCONCAT
:
257 mm
< MM_add
? LJ_ERR_FFI_BADCOMP
: LJ_ERR_FFI_BADARITH
,
260 return lj_meta_tailcall(L
, tv
);
263 /* Arithmetic operators for cdata. */
264 int lj_carith_op(lua_State
*L
, MMS mm
)
266 CTState
*cts
= ctype_cts(L
);
268 if (carith_checkarg(L
, cts
, &ca
)) {
269 if (carith_int64(L
, cts
, &ca
, mm
) || carith_ptr(L
, cts
, &ca
, mm
)) {
270 copyTV(L
, &G(L
)->tmptv2
, L
->top
-1); /* Remember for trace recorder. */
274 return lj_carith_meta(L
, cts
, &ca
, mm
);
277 /* -- 64 bit bit operations helpers --------------------------------------- */
280 #define B64DEF(name) \
281 static LJ_AINLINE uint64_t lj_carith_##name(uint64_t x, int32_t sh)
283 /* Not inlined on 32 bit archs, since some of these are quite lengthy. */
284 #define B64DEF(name) \
285 uint64_t LJ_NOINLINE lj_carith_##name(uint64_t x, int32_t sh)
288 B64DEF(shl64
) { return x
<< (sh
&63); }
289 B64DEF(shr64
) { return x
>> (sh
&63); }
290 B64DEF(sar64
) { return (uint64_t)((int64_t)x
>> (sh
&63)); }
291 B64DEF(rol64
) { return lj_rol(x
, (sh
&63)); }
292 B64DEF(ror64
) { return lj_ror(x
, (sh
&63)); }
296 uint64_t lj_carith_shift64(uint64_t x
, int32_t sh
, int op
)
299 case IR_BSHL
-IR_BSHL
: x
= lj_carith_shl64(x
, sh
); break;
300 case IR_BSHR
-IR_BSHL
: x
= lj_carith_shr64(x
, sh
); break;
301 case IR_BSAR
-IR_BSHL
: x
= lj_carith_sar64(x
, sh
); break;
302 case IR_BROL
-IR_BSHL
: x
= lj_carith_rol64(x
, sh
); break;
303 case IR_BROR
-IR_BSHL
: x
= lj_carith_ror64(x
, sh
); break;
304 default: lua_assert(0); break;
309 /* Equivalent to lj_lib_checkbit(), but handles cdata. */
310 uint64_t lj_carith_check64(lua_State
*L
, int narg
, CTypeID
*id
)
312 TValue
*o
= L
->base
+ narg
-1;
315 lj_err_argt(L
, narg
, LUA_TNUMBER
);
316 } else if (LJ_LIKELY(tvisnumber(o
))) {
318 } else if (tviscdata(o
)) {
319 CTState
*cts
= ctype_cts(L
);
320 uint8_t *sp
= (uint8_t *)cdataptr(cdataV(o
));
321 CTypeID sid
= cdataV(o
)->ctypeid
;
322 CType
*s
= ctype_get(cts
, sid
);
324 if (ctype_isref(s
->info
)) {
326 sid
= ctype_cid(s
->info
);
328 s
= ctype_raw(cts
, sid
);
329 if (ctype_isenum(s
->info
)) s
= ctype_child(cts
, s
);
330 if ((s
->info
& (CTMASK_NUM
|CTF_BOOL
|CTF_FP
|CTF_UNSIGNED
)) ==
331 CTINFO(CT_NUM
, CTF_UNSIGNED
) && s
->size
== 8)
332 *id
= CTID_UINT64
; /* Use uint64_t, since it has the highest rank. */
334 *id
= CTID_INT64
; /* Use int64_t, unless already set. */
335 lj_cconv_ct_ct(cts
, ctype_get(cts
, *id
), s
,
336 (uint8_t *)&x
, sp
, CCF_ARG(narg
));
338 } else if (!(tvisstr(o
) && lj_strscan_number(strV(o
), o
))) {
341 if (LJ_LIKELY(tvisint(o
))) {
342 return (uint32_t)intV(o
);
344 int32_t i
= lj_num2bit(numV(o
));
345 if (LJ_DUALNUM
) setintV(o
, i
);
351 /* -- 64 bit integer arithmetic helpers ----------------------------------- */
353 #if LJ_32 && LJ_HASJIT
354 /* Signed/unsigned 64 bit multiplication. */
355 int64_t lj_carith_mul64(int64_t a
, int64_t b
)
361 /* Unsigned 64 bit division. */
362 uint64_t lj_carith_divu64(uint64_t a
, uint64_t b
)
364 if (b
== 0) return U64x(80000000,00000000);
368 /* Signed 64 bit division. */
369 int64_t lj_carith_divi64(int64_t a
, int64_t b
)
371 if (b
== 0 || (a
== (int64_t)U64x(80000000,00000000) && b
== -1))
372 return U64x(80000000,00000000);
376 /* Unsigned 64 bit modulo. */
377 uint64_t lj_carith_modu64(uint64_t a
, uint64_t b
)
379 if (b
== 0) return U64x(80000000,00000000);
383 /* Signed 64 bit modulo. */
384 int64_t lj_carith_modi64(int64_t a
, int64_t b
)
386 if (b
== 0) return U64x(80000000,00000000);
387 if (a
== (int64_t)U64x(80000000,00000000) && b
== -1) return 0;
391 /* Unsigned 64 bit x^k. */
392 uint64_t lj_carith_powu64(uint64_t x
, uint64_t k
)
397 for (; (k
& 1) == 0; k
>>= 1) x
*= x
;
399 if ((k
>>= 1) != 0) {
411 /* Signed 64 bit x^k. */
412 int64_t lj_carith_powi64(int64_t x
, int64_t k
)
418 return U64x(7fffffff
,ffffffff
);
422 return (k
& 1) ? -1 : 1;
426 return (int64_t)lj_carith_powu64((uint64_t)x
, (uint64_t)k
);