return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs));
}
+#if LJ_HASFFI
+static IRRef split_bitshift(jit_State *J, IRRef1 *hisubst,
+ IRIns *oir, IRIns *nir, IRIns *ir)
+{
+ IROp op = ir->o;
+ IRRef kref = nir->op2;
+ if (irref_isk(kref)) { /* Optimize constant shifts. */
+ int32_t k = (IR(kref)->i & 63);
+ IRRef lo = nir->op1, hi = hisubst[ir->op1];
+ if (op == IR_BROL || op == IR_BROR) {
+ if (op == IR_BROR) k = (-k & 63);
+ if (k >= 32) { IRRef t = lo; lo = hi; hi = t; k -= 32; }
+ if (k == 0) {
+ passthrough:
+ J->cur.nins--;
+ ir->prev = lo;
+ return hi;
+ } else {
+ TRef k1, k2;
+ IRRef t1, t2, t3, t4;
+ J->cur.nins--;
+ k1 = lj_ir_kint(J, k);
+ k2 = lj_ir_kint(J, (-k & 31));
+ t1 = split_emit(J, IRTI(IR_BSHL), lo, k1);
+ t2 = split_emit(J, IRTI(IR_BSHL), hi, k1);
+ t3 = split_emit(J, IRTI(IR_BSHR), lo, k2);
+ t4 = split_emit(J, IRTI(IR_BSHR), hi, k2);
+ ir->prev = split_emit(J, IRTI(IR_BOR), t1, t4);
+ return split_emit(J, IRTI(IR_BOR), t2, t3);
+ }
+ } else if (k == 0) {
+ goto passthrough;
+ } else if (k < 32) {
+ if (op == IR_BSHL) {
+ IRRef t1 = split_emit(J, IRTI(IR_BSHL), hi, kref);
+ IRRef t2 = split_emit(J, IRTI(IR_BSHR), lo, lj_ir_kint(J, (-k&31)));
+ return split_emit(J, IRTI(IR_BOR), t1, t2);
+ } else {
+ IRRef t1 = ir->prev, t2;
+ lua_assert(op == IR_BSHR || op == IR_BSAR);
+ nir->o = IR_BSHR;
+ t2 = split_emit(J, IRTI(IR_BSHL), hi, lj_ir_kint(J, (-k&31)));
+ ir->prev = split_emit(J, IRTI(IR_BOR), t1, t2);
+ return split_emit(J, IRTI(op), hi, kref);
+ }
+ } else {
+ if (op == IR_BSHL) {
+ if (k == 32)
+ J->cur.nins--;
+ else
+ lo = ir->prev;
+ ir->prev = lj_ir_kint(J, 0);
+ return lo;
+ } else {
+ lua_assert(op == IR_BSHR || op == IR_BSAR);
+ if (k == 32) {
+ J->cur.nins--;
+ ir->prev = hi;
+ } else {
+ nir->op1 = hi;
+ }
+ if (op == IR_BSHR)
+ return lj_ir_kint(J, 0);
+ else
+ return split_emit(J, IRTI(IR_BSAR), hi, lj_ir_kint(J, 31));
+ }
+ }
+ }
+ return split_call_li(J, hisubst, oir, ir,
+ op - IR_BSHL + IRCALL_lj_carith_shl64);
+}
+
+static IRRef split_bitop(jit_State *J, IRRef1 *hisubst,
+ IRIns *nir, IRIns *ir)
+{
+ IROp op = ir->o;
+ IRRef hi, kref = nir->op2;
+ if (irref_isk(kref)) { /* Optimize bit operations with lo constant. */
+ int32_t k = IR(kref)->i;
+ if (k == 0 || k == -1) {
+ if (op == IR_BAND) k = ~k;
+ if (k == 0) {
+ J->cur.nins--;
+ ir->prev = nir->op1;
+ } else if (op == IR_BXOR) {
+ nir->o = IR_BNOT;
+ nir->op2 = 0;
+ } else {
+ J->cur.nins--;
+ ir->prev = kref;
+ }
+ }
+ }
+ hi = hisubst[ir->op1];
+ kref = hisubst[ir->op2];
+ if (irref_isk(kref)) { /* Optimize bit operations with hi constant. */
+ int32_t k = IR(kref)->i;
+ if (k == 0 || k == -1) {
+ if (op == IR_BAND) k = ~k;
+ if (k == 0) {
+ return hi;
+ } else if (op == IR_BXOR) {
+ return split_emit(J, IRTI(IR_BNOT), hi, 0);
+ } else {
+ return kref;
+ }
+ }
+ }
+ return split_emit(J, IRTI(op), hi, kref);
+}
+#endif
+
+ /* Substitute references of a snapshot. */
+ static void split_subst_snap(jit_State *J, SnapShot *snap, IRIns *oir)
+ {
+ SnapEntry *map = &J->cur.snapmap[snap->mapofs];
+ MSize n, nent = snap->nent;
+ for (n = 0; n < nent; n++) {
+ SnapEntry sn = map[n];
+ IRIns *ir = &oir[snap_ref(sn)];
+ if (!(LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))))
+ map[n] = ((sn & 0xffff0000) | ir->prev);
+ }
+ }
+
/* Transform the old IR to the new IR. */
static void split_ir(jit_State *J)
{
IRRef nins = J->cur.nins, nk = J->cur.nk;
MSize irlen = nins - nk;
MSize need = (irlen+1)*(sizeof(IRIns) + sizeof(IRRef1));
- IRIns *oir = (IRIns *)lj_str_needbuf(J->L, &G(J->L)->tmpbuf, need);
+ IRIns *oir = (IRIns *)lj_buf_tmp(J->L, need);
IRRef1 *hisubst;
- IRRef ref;
+ IRRef ref, snref;
+ SnapShot *snap;
/* Copy old IR to buffer. */
memcpy(oir, IR(nk), irlen*sizeof(IRIns));