void shuffle2(Asm& as, PhysReg s0, PhysReg s1, PhysReg d0, PhysReg d1) { if (s0 == InvalidReg && s1 == InvalidReg && d0 == InvalidReg && d1 == InvalidReg) return; assert(s0 != s1); assert(!s0.isSIMD() || s1 == InvalidReg); // never 2 XMMs assert(!d0.isSIMD() || d1 == InvalidReg); // never 2 XMMs if (d0 == s1 && d1 != InvalidReg) { assert(d0 != d1); if (d1 == s0) { as. xchgq (s1, s0); } else { as. movq (s1, d1); // save s1 first; d1 != s0 as. movq (s0, d0); } } else if (d0.isSIMD() && s0.isGP() && s1.isGP()) { // move 2 gpr to 1 xmm assert(d0 != rCgXMM0); // xmm0 is reserved for scratch as. movq_rx(s0, d0); as. movq_rx(s1, rCgXMM0); as. unpcklpd(rCgXMM0, d0); // s1 -> d0[1] } else { if (d0 != InvalidReg) emitMovRegReg(as, s0, d0); // d0 != s1 if (d1 != InvalidReg) emitMovRegReg(as, s1, d1); } }
PhysReg lookup(Vreg vreg, VregKind kind) { auto ivl = xls.intervals[vreg]; if (!ivl || vreg.isPhys()) return vreg; PhysReg reg = ivl->childAt(pos)->reg; assert((kind == VregKind::Gpr && reg.isGP()) || (kind == VregKind::Simd && reg.isSIMD()) || (kind == VregKind::Any && reg != InvalidReg)); return reg; }