ljx_bitwise.c (4736B)
1 #include "lj_obj.h" 2 #include "lj_strscan.h" 3 #if LJ_HASFFI 4 #include "lj_ctype.h" 5 #include "lj_cdata.h" 6 #include "lj_cconv.h" 7 #endif 8 #include "ljx_bitwise.h" 9 #include "lj_crecord.h" 10 #include "lj_dispatch.h" 11 #include "lj_iropt.h" 12 13 #if LJ_53 14 /* Decode arguments for interpreter dispatch */ 15 static int get_arg(lua_State *L, cTValue *o, int64_t *res) 16 { 17 TValue tmp; 18 #if LJ_HASFFI 19 CTypeID id = 0; 20 *res = 0; 21 if (tviscdata(o)) { 22 CTState *cts = ctype_cts(L); 23 uint8_t *sp = (uint8_t *)cdataptr(cdataV(o)); 24 CTypeID sid = cdataV(o)->ctypeid; 25 CType *s = ctype_get(cts, sid); 26 if (ctype_isref(s->info)) { 27 sp = *(void **)sp; 28 sid = ctype_cid(s->info); 29 } 30 s = ctype_raw(cts, sid); 31 if (ctype_isenum(s->info)) s = ctype_child(cts, s); 32 if ((s->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) == 33 CTINFO(CT_NUM, CTF_UNSIGNED) && s->size == 8) 34 id = CTID_UINT64; /* Use uint64_t, since it has the highest rank. */ 35 else 36 id = CTID_INT64; /* Use int64_t, unless already set. */ 37 if (lj_cconv_ct_ct(cts, ctype_get(cts, id), s, 38 (uint8_t *)res, sp, CCF_NOERROR) < 0) 39 return -1; 40 return id; 41 } else 42 #endif 43 if (tvisstr(o)) { 44 if (!lj_strscan_number(strV(o), &tmp)) 45 return -1; 46 o = &tmp; 47 } 48 if (LJ_LIKELY(tvisint(o))) { 49 *res = (uint32_t)intV(o); 50 return 0; 51 } 52 if (LJ_LIKELY(tvisnumber(o))) { 53 *res = (uint32_t)lj_num2bit(numV(o)); 54 return 0; 55 } 56 return -1; 57 } 58 59 #define B_METHODS(_) \ 60 _(bnot,=~x) _(idiv, /=y) _(band, &=y) _(bor, |=y) \ 61 _(bxor, ^=y) _(shl, <<=y) _(shr, >>=y) 62 #define CASE(name, suff) \ 63 case MM_##name: x suff; break; 64 65 int ljx_vm_foldbit(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc, 66 MMS mm) 67 { 68 int id1, id2; 69 int64_t a,b; 70 71 if (((id1 = get_arg(L, rb, &a)) == -1) || ((id2 = get_arg(L, rc, &b)) == -1)) 72 return -1; /* call metamethod */ 73 /* expand to common type, with the exception of shifts */ 74 if (mm < MM_shl && id2 > id1) 75 id1 = id2; 76 /* int32 */ 77 if (!id1) { 78 uint32_t x = a; 79 uint32_t y = b; 80 switch (mm) { 81 B_METHODS(CASE) 82 default: return -1; 83 } 84 setintV(ra, x); 85 } 86 #if LJ_HASFFI 87 else { 88 uint64_t x = a; 89 uint64_t y = b; 90 GCcdata *cd; 91 switch (mm) { 92 B_METHODS(CASE) 93 default: return -1; 94 } 95 cd = lj_cdata_new_(L, id1, 8); 96 *(uint64_t *)cdataptr(cd) = x; 97 setcdataV(L, ra, cd); 98 } 99 #endif 100 return id1; 101 } 102 103 #define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J)) 104 #define emitconv(a, dt, st, flags) \ 105 emitir(IRT(IR_CONV, (dt)), (a), (st)|((dt) << 5)|(flags)) 106 107 /* Same as lj_opt_narrow_tobit, but does not raise trace error. */ 108 static TRef bit_narrow_int(jit_State *J, TRef r) 109 { 110 if (tref_isstr(r)) 111 r = emitir(IRTG(IR_STRTO, IRT_NUM), r, 0); 112 if (tref_isnum(r)) /* Conversion may be narrowed, too. See above. */ 113 return emitir(IRTI(IR_TOBIT), r, lj_ir_knum_tobit(J)); 114 if (!tref_isinteger(r)) 115 return 0; 116 return lj_opt_narrow_stripov(J, r, IR_SUBOV, (IRT_INT<<5)|IRT_INT|IRCONV_TOBIT); 117 } 118 119 /* Narrow to specified type. */ 120 static TRef bit_narrow_id(jit_State *J, CTypeID wantid, TRef tr, cTValue *o) 121 { 122 CTState *cts = ctype_ctsG(J2G(J)); 123 if (!wantid) 124 return bit_narrow_int(J, tr); 125 #if LJ_HASJIT && LJ_HASFFI 126 return lj_crec_ct_tv(J, ctype_get(cts, wantid), 0, tr, o); 127 #else 128 return 0; 129 #endif 130 } 131 132 /* Record. */ 133 TRef ljx_rec_bitwise(jit_State *J, TRef rb, TRef rc, cTValue *rbv, cTValue *rcv, MMS mm) 134 { 135 CTState *cts = ctype_ctsG(J2G(J)); 136 TRef r1, r2 = 0; 137 CTypeID id1 = 0, id2 = 0; 138 #if LJ_HASJIT && LJ_HASFFI 139 id1 = lj_crec_bit64_type(cts, rbv); 140 id2 = lj_crec_bit64_type(cts, rcv); 141 #endif 142 /* For shifts, the shift arg might stay as int */ 143 if (mm >= MM_shl) { 144 if (id2) { 145 r2 = bit_narrow_id(J, CTID_INT64, rc, rcv); 146 if (!tref_isinteger(r2)) 147 r2 = emitconv(r2, IRT_INT, tref_type(r2), 0); 148 } else { 149 r2 = bit_narrow_int(J, rc); 150 if (!r2) return 0; /* Not even int? Bail. */ 151 } 152 id2 = 0; /* The arg is never widest */ 153 } 154 if (id2 > id1) /* Determine widest type */ 155 id1 = id2; 156 r1 = bit_narrow_id(J, id1, rb, rbv); /* And resolve those */ 157 if (!r1) return 0; 158 159 if (!r2 && mm != MM_bnot) { /* Only if not shift or unary */ 160 r2 = bit_narrow_id(J, id1, rc, rcv); 161 if (!r2) return 0; 162 } 163 164 /* All set now. id1 holds the output type (or 0 if INT). */ 165 uint32_t irop = IR_BNOT + mm - MM_bnot; 166 if (mm == MM_idiv) 167 irop = IR_DIV; 168 /* Type-specific and boxed? */ 169 #if LJ_HASJIT && LJ_HASFFI 170 if (id1) { 171 TRef tr = emitir(IRT(irop, id1-CTID_INT64+IRT_I64), r1, r2); 172 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id1), tr); 173 } 174 #endif 175 /* Otherwise plain I32 */ 176 return emitir(IRTI(irop), r1, r2); 177 } 178 179 #endif