diff options
Diffstat (limited to 'lib/Target/X86/X86InstructionSelector.cpp')
| -rw-r--r-- | lib/Target/X86/X86InstructionSelector.cpp | 214 | 
1 files changed, 108 insertions, 106 deletions
diff --git a/lib/Target/X86/X86InstructionSelector.cpp b/lib/Target/X86/X86InstructionSelector.cpp index d65eb1de8d09..de58d719acb4 100644 --- a/lib/Target/X86/X86InstructionSelector.cpp +++ b/lib/Target/X86/X86InstructionSelector.cpp @@ -56,13 +56,9 @@ private:    bool selectImpl(MachineInstr &I) const;    // TODO: remove after suported by Tablegen-erated instruction selection. -  unsigned getFAddOp(LLT &Ty, const RegisterBank &RB) const; -  unsigned getFSubOp(LLT &Ty, const RegisterBank &RB) const;    unsigned getLoadStoreOp(LLT &Ty, const RegisterBank &RB, unsigned Opc,                            uint64_t Alignment) const; -  bool selectBinaryOp(MachineInstr &I, MachineRegisterInfo &MRI, -                      MachineFunction &MF) const;    bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,                           MachineFunction &MF) const;    bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI, @@ -71,6 +67,10 @@ private:                        MachineFunction &MF) const;    bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI,                     MachineFunction &MF) const; +  bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI, +                  MachineFunction &MF) const; +  bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI, +                 MachineFunction &MF) const;    const X86TargetMachine &TM;    const X86Subtarget &STI; @@ -226,13 +226,11 @@ bool X86InstructionSelector::select(MachineInstr &I) const {           "Generic instruction has unexpected implicit operands\n");    if (selectImpl(I)) -     return true; +    return true;    DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));    // TODO: This should be implemented by tblgen. -  if (selectBinaryOp(I, MRI, MF)) -    return true;    if (selectLoadStoreOp(I, MRI, MF))      return true;    if (selectFrameIndexOrGep(I, MRI, MF)) @@ -241,109 +239,14 @@ bool X86InstructionSelector::select(MachineInstr &I) const {      return true;    if (selectTrunc(I, MRI, MF))      return true; +  if (selectZext(I, MRI, MF)) +    return true; +  if (selectCmp(I, MRI, MF)) +    return true;    return false;  } -unsigned X86InstructionSelector::getFAddOp(LLT &Ty, -                                           const RegisterBank &RB) const { - -  if (X86::VECRRegBankID != RB.getID()) -    return TargetOpcode::G_FADD; - -  if (Ty == LLT::scalar(32)) { -    if (STI.hasAVX512()) { -      return X86::VADDSSZrr; -    } else if (STI.hasAVX()) { -      return X86::VADDSSrr; -    } else if (STI.hasSSE1()) { -      return X86::ADDSSrr; -    } -  } else if (Ty == LLT::scalar(64)) { -    if (STI.hasAVX512()) { -      return X86::VADDSDZrr; -    } else if (STI.hasAVX()) { -      return X86::VADDSDrr; -    } else if (STI.hasSSE2()) { -      return X86::ADDSDrr; -    } -  } else if (Ty == LLT::vector(4, 32)) { -    if ((STI.hasAVX512()) && (STI.hasVLX())) { -      return X86::VADDPSZ128rr; -    } else if (STI.hasAVX()) { -      return X86::VADDPSrr; -    } else if (STI.hasSSE1()) { -      return X86::ADDPSrr; -    } -  } - -  return TargetOpcode::G_FADD; -} - -unsigned X86InstructionSelector::getFSubOp(LLT &Ty, -                                           const RegisterBank &RB) const { - -  if (X86::VECRRegBankID != RB.getID()) -    return TargetOpcode::G_FSUB; - -  if (Ty == LLT::scalar(32)) { -    if (STI.hasAVX512()) { -      return X86::VSUBSSZrr; -    } else if (STI.hasAVX()) { -      return X86::VSUBSSrr; -    } else if (STI.hasSSE1()) { -      return X86::SUBSSrr; -    } -  } else if (Ty == LLT::scalar(64)) { -    if (STI.hasAVX512()) { -      return X86::VSUBSDZrr; -    } else if (STI.hasAVX()) { -      return X86::VSUBSDrr; -    } else if (STI.hasSSE2()) { -      return X86::SUBSDrr; -    } -  } else if (Ty == LLT::vector(4, 32)) { -    if ((STI.hasAVX512()) && (STI.hasVLX())) { -      return X86::VSUBPSZ128rr; -    } else if (STI.hasAVX()) { -      return X86::VSUBPSrr; -    } else if (STI.hasSSE1()) { -      return X86::SUBPSrr; -    } -  } - -  return TargetOpcode::G_FSUB; -} - -bool X86InstructionSelector::selectBinaryOp(MachineInstr &I, -                                            MachineRegisterInfo &MRI, -                                            MachineFunction &MF) const { - -  const unsigned DefReg = I.getOperand(0).getReg(); -  LLT Ty = MRI.getType(DefReg); -  const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); - -  unsigned NewOpc = I.getOpcode(); - -  switch (NewOpc) { -  case TargetOpcode::G_FADD: -    NewOpc = getFAddOp(Ty, RB); -    break; -  case TargetOpcode::G_FSUB: -    NewOpc = getFSubOp(Ty, RB); -    break; -  default: -    break; -  } - -  if (NewOpc == I.getOpcode()) -    return false; - -  I.setDesc(TII.get(NewOpc)); - -  return constrainSelectedInstRegOperands(I, TII, TRI, RBI); -} -  unsigned X86InstructionSelector::getLoadStoreOp(LLT &Ty, const RegisterBank &RB,                                                  unsigned Opc,                                                  uint64_t Alignment) const { @@ -562,6 +465,105 @@ bool X86InstructionSelector::selectTrunc(MachineInstr &I,    return true;  } +bool X86InstructionSelector::selectZext(MachineInstr &I, +                                        MachineRegisterInfo &MRI, +                                        MachineFunction &MF) const { +  if (I.getOpcode() != TargetOpcode::G_ZEXT) +    return false; + +  const unsigned DstReg = I.getOperand(0).getReg(); +  const unsigned SrcReg = I.getOperand(1).getReg(); + +  const LLT DstTy = MRI.getType(DstReg); +  const LLT SrcTy = MRI.getType(SrcReg); + +  if (SrcTy == LLT::scalar(1)) { + +    unsigned AndOpc; +    if (DstTy == LLT::scalar(32)) +      AndOpc = X86::AND32ri8; +    else if (DstTy == LLT::scalar(64)) +      AndOpc = X86::AND64ri8; +    else +      return false; + +    const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); +    unsigned DefReg = +        MRI.createVirtualRegister(getRegClassForTypeOnBank(DstTy, RegBank)); + +    BuildMI(*I.getParent(), I, I.getDebugLoc(), +            TII.get(TargetOpcode::SUBREG_TO_REG), DefReg) +        .addImm(0) +        .addReg(SrcReg) +        .addImm(X86::sub_8bit); + +    MachineInstr &AndInst = +        *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg) +             .addReg(DefReg) +             .addImm(1); + +    constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI); + +    I.eraseFromParent(); +    return true; +  } + +  return false; +} + +bool X86InstructionSelector::selectCmp(MachineInstr &I, +                                       MachineRegisterInfo &MRI, +                                       MachineFunction &MF) const { +  if (I.getOpcode() != TargetOpcode::G_ICMP) +    return false; + +  X86::CondCode CC; +  bool SwapArgs; +  std::tie(CC, SwapArgs) = X86::getX86ConditionCode( +      (CmpInst::Predicate)I.getOperand(1).getPredicate()); +  unsigned OpSet = X86::getSETFromCond(CC); + +  unsigned LHS = I.getOperand(2).getReg(); +  unsigned RHS = I.getOperand(3).getReg(); + +  if (SwapArgs) +    std::swap(LHS, RHS); + +  unsigned OpCmp; +  LLT Ty = MRI.getType(LHS); + +  switch (Ty.getSizeInBits()) { +  default: +    return false; +  case 8: +    OpCmp = X86::CMP8rr; +    break; +  case 16: +    OpCmp = X86::CMP16rr; +    break; +  case 32: +    OpCmp = X86::CMP32rr; +    break; +  case 64: +    OpCmp = X86::CMP64rr; +    break; +  } + +  MachineInstr &CmpInst = +      *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp)) +           .addReg(LHS) +           .addReg(RHS); + +  MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(), +                                   TII.get(OpSet), I.getOperand(0).getReg()); + +  constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI); +  constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI); + +  I.eraseFromParent(); +  return true; +} +  InstructionSelector *  llvm::createX86InstructionSelector(const X86TargetMachine &TM,                                     X86Subtarget &Subtarget,  | 
