Example #1
0
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);
    }
}
Example #2
0
 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;
 }
Example #3
0
std::string show(PhysReg r) {
  switch (arch()) {
    case Arch::X64:
      return r.type() == PhysReg::GP   ? reg::regname(Reg64(r)) :
             r.type() == PhysReg::SIMD ? reg::regname(RegXMM(r)) :
          /* r.type() == PhysReg::SF)  ? */ reg::regname(RegSF(r));

    case Arch::ARM:
      if (r.isSF()) return "SF";

      return folly::to<std::string>(
        r.isGP() ? (vixl::Register(r).size() == vixl::kXRegSize ? 'x' : 'w')
                 : (vixl::FPRegister(r).size() == vixl::kSRegSize ? 's' : 'd'),
        ((vixl::CPURegister)r).code()
      );

    case Arch::PPC64:
      return r.type() == PhysReg::GP   ? ppc64_asm::reg::regname(Reg64(r)) :
             r.type() == PhysReg::SIMD ? ppc64_asm::reg::regname(RegXMM(r)) :
          /* r.type() == PhysReg::SF)  ? */ ppc64_asm::reg::regname(RegSF(r));
  }
  not_reached();
}
Example #4
0
// Logical register move: ensures the value in src will be in dest
// after execution, but might do so in strange ways. Do not count on
// being able to smash dest to a different register in the future, e.g.
void emitMovRegReg(Asm& as, PhysReg srcReg, PhysReg dstReg) {
  assert(srcReg != InvalidReg);
  assert(dstReg != InvalidReg);

  if (srcReg == dstReg) return;

  if (srcReg.isGP()) {
    if (dstReg.isGP()) {                 // GP => GP
      as. movq(srcReg, dstReg);
    } else {                             // GP => XMM
      // This generates a movq x86 instruction, which zero extends
      // the 64-bit value in srcReg into a 128-bit XMM register
      as. mov_reg64_xmm(srcReg, dstReg);
    }
  } else {
    if (dstReg.isGP()) {                 // XMM => GP
      as. mov_xmm_reg64(srcReg, dstReg);
    } else {                             // XMM => XMM
      // This copies all 128 bits in XMM,
      // thus avoiding partial register stalls
      as. movdqa(srcReg, dstReg);
    }
  }
}