xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15f757f3fSDimitry Andric //===- X86InstructionSelector.cpp -----------------------------------------===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric /// \file
95f757f3fSDimitry Andric /// This file implements the targeting of the InstructionSelector class for
105f757f3fSDimitry Andric /// X86.
115f757f3fSDimitry Andric /// \todo This should be generated by TableGen.
125f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
135f757f3fSDimitry Andric 
145f757f3fSDimitry Andric #include "MCTargetDesc/X86BaseInfo.h"
155f757f3fSDimitry Andric #include "X86.h"
165f757f3fSDimitry Andric #include "X86InstrBuilder.h"
175f757f3fSDimitry Andric #include "X86InstrInfo.h"
185f757f3fSDimitry Andric #include "X86RegisterBankInfo.h"
195f757f3fSDimitry Andric #include "X86RegisterInfo.h"
205f757f3fSDimitry Andric #include "X86Subtarget.h"
215f757f3fSDimitry Andric #include "X86TargetMachine.h"
225f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
235f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
245f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
255f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h"
265f757f3fSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
275f757f3fSDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
285f757f3fSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
295f757f3fSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
305f757f3fSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
315f757f3fSDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
325f757f3fSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
335f757f3fSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
345f757f3fSDimitry Andric #include "llvm/CodeGen/RegisterBank.h"
355f757f3fSDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
365f757f3fSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
37*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
385f757f3fSDimitry Andric #include "llvm/IR/DataLayout.h"
395f757f3fSDimitry Andric #include "llvm/IR/InstrTypes.h"
405f757f3fSDimitry Andric #include "llvm/IR/IntrinsicsX86.h"
415f757f3fSDimitry Andric #include "llvm/Support/AtomicOrdering.h"
425f757f3fSDimitry Andric #include "llvm/Support/CodeGen.h"
435f757f3fSDimitry Andric #include "llvm/Support/Debug.h"
445f757f3fSDimitry Andric #include "llvm/Support/ErrorHandling.h"
455f757f3fSDimitry Andric #include "llvm/Support/MathExtras.h"
465f757f3fSDimitry Andric #include "llvm/Support/raw_ostream.h"
475f757f3fSDimitry Andric #include <cassert>
485f757f3fSDimitry Andric #include <cstdint>
495f757f3fSDimitry Andric #include <tuple>
505f757f3fSDimitry Andric 
515f757f3fSDimitry Andric #define DEBUG_TYPE "X86-isel"
525f757f3fSDimitry Andric 
535f757f3fSDimitry Andric using namespace llvm;
545f757f3fSDimitry Andric 
555f757f3fSDimitry Andric namespace {
565f757f3fSDimitry Andric 
575f757f3fSDimitry Andric #define GET_GLOBALISEL_PREDICATE_BITSET
585f757f3fSDimitry Andric #include "X86GenGlobalISel.inc"
595f757f3fSDimitry Andric #undef GET_GLOBALISEL_PREDICATE_BITSET
605f757f3fSDimitry Andric 
615f757f3fSDimitry Andric class X86InstructionSelector : public InstructionSelector {
625f757f3fSDimitry Andric public:
635f757f3fSDimitry Andric   X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
645f757f3fSDimitry Andric                          const X86RegisterBankInfo &RBI);
655f757f3fSDimitry Andric 
665f757f3fSDimitry Andric   bool select(MachineInstr &I) override;
675f757f3fSDimitry Andric   static const char *getName() { return DEBUG_TYPE; }
685f757f3fSDimitry Andric 
695f757f3fSDimitry Andric private:
705f757f3fSDimitry Andric   /// tblgen-erated 'select' implementation, used as the initial selector for
715f757f3fSDimitry Andric   /// the patterns that don't require complex C++.
725f757f3fSDimitry Andric   bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
735f757f3fSDimitry Andric 
745f757f3fSDimitry Andric   // TODO: remove after supported by Tablegen-erated instruction selection.
755f757f3fSDimitry Andric   unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc,
765f757f3fSDimitry Andric                           Align Alignment) const;
775f757f3fSDimitry Andric 
785f757f3fSDimitry Andric   bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
795f757f3fSDimitry Andric                          MachineFunction &MF) const;
805f757f3fSDimitry Andric   bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI,
815f757f3fSDimitry Andric                              MachineFunction &MF) const;
825f757f3fSDimitry Andric   bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI,
835f757f3fSDimitry Andric                          MachineFunction &MF) const;
845f757f3fSDimitry Andric   bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
855f757f3fSDimitry Andric                       MachineFunction &MF) const;
865f757f3fSDimitry Andric   bool selectTruncOrPtrToInt(MachineInstr &I, MachineRegisterInfo &MRI,
875f757f3fSDimitry Andric                              MachineFunction &MF) const;
885f757f3fSDimitry Andric   bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
895f757f3fSDimitry Andric                   MachineFunction &MF) const;
905f757f3fSDimitry Andric   bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI,
915f757f3fSDimitry Andric                     MachineFunction &MF) const;
925f757f3fSDimitry Andric   bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
935f757f3fSDimitry Andric                  MachineFunction &MF) const;
945f757f3fSDimitry Andric   bool selectFCmp(MachineInstr &I, MachineRegisterInfo &MRI,
955f757f3fSDimitry Andric                   MachineFunction &MF) const;
965f757f3fSDimitry Andric   bool selectUAddSub(MachineInstr &I, MachineRegisterInfo &MRI,
975f757f3fSDimitry Andric                      MachineFunction &MF) const;
985f757f3fSDimitry Andric   bool selectDebugInstr(MachineInstr &I, MachineRegisterInfo &MRI) const;
995f757f3fSDimitry Andric   bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
1005f757f3fSDimitry Andric   bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
1015f757f3fSDimitry Andric                            MachineFunction &MF);
1025f757f3fSDimitry Andric   bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
1035f757f3fSDimitry Andric                          MachineFunction &MF);
1045f757f3fSDimitry Andric   bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI,
1055f757f3fSDimitry Andric                     MachineFunction &MF) const;
1065f757f3fSDimitry Andric   bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
1075f757f3fSDimitry Andric                      MachineFunction &MF) const;
1085f757f3fSDimitry Andric   bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
1095f757f3fSDimitry Andric                         MachineFunction &MF) const;
1105f757f3fSDimitry Andric   bool selectTurnIntoCOPY(MachineInstr &I, MachineRegisterInfo &MRI,
1115f757f3fSDimitry Andric                           const unsigned DstReg,
1125f757f3fSDimitry Andric                           const TargetRegisterClass *DstRC,
1135f757f3fSDimitry Andric                           const unsigned SrcReg,
1145f757f3fSDimitry Andric                           const TargetRegisterClass *SrcRC) const;
1155f757f3fSDimitry Andric   bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
1165f757f3fSDimitry Andric                      MachineFunction &MF) const;
1175f757f3fSDimitry Andric   bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
1185f757f3fSDimitry Andric   bool selectMulDivRem(MachineInstr &I, MachineRegisterInfo &MRI,
1195f757f3fSDimitry Andric                        MachineFunction &MF) const;
1205f757f3fSDimitry Andric   bool selectSelect(MachineInstr &I, MachineRegisterInfo &MRI,
1215f757f3fSDimitry Andric                     MachineFunction &MF) const;
1225f757f3fSDimitry Andric 
1235f757f3fSDimitry Andric   // emit insert subreg instruction and insert it before MachineInstr &I
1245f757f3fSDimitry Andric   bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
1255f757f3fSDimitry Andric                         MachineRegisterInfo &MRI, MachineFunction &MF) const;
1265f757f3fSDimitry Andric   // emit extract subreg instruction and insert it before MachineInstr &I
1275f757f3fSDimitry Andric   bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
1285f757f3fSDimitry Andric                          MachineRegisterInfo &MRI, MachineFunction &MF) const;
1295f757f3fSDimitry Andric 
1305f757f3fSDimitry Andric   const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const;
1315f757f3fSDimitry Andric   const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg,
1325f757f3fSDimitry Andric                                          MachineRegisterInfo &MRI) const;
1335f757f3fSDimitry Andric 
1345f757f3fSDimitry Andric   const X86TargetMachine &TM;
1355f757f3fSDimitry Andric   const X86Subtarget &STI;
1365f757f3fSDimitry Andric   const X86InstrInfo &TII;
1375f757f3fSDimitry Andric   const X86RegisterInfo &TRI;
1385f757f3fSDimitry Andric   const X86RegisterBankInfo &RBI;
1395f757f3fSDimitry Andric 
1405f757f3fSDimitry Andric #define GET_GLOBALISEL_PREDICATES_DECL
1415f757f3fSDimitry Andric #include "X86GenGlobalISel.inc"
1425f757f3fSDimitry Andric #undef GET_GLOBALISEL_PREDICATES_DECL
1435f757f3fSDimitry Andric 
1445f757f3fSDimitry Andric #define GET_GLOBALISEL_TEMPORARIES_DECL
1455f757f3fSDimitry Andric #include "X86GenGlobalISel.inc"
1465f757f3fSDimitry Andric #undef GET_GLOBALISEL_TEMPORARIES_DECL
1475f757f3fSDimitry Andric };
1485f757f3fSDimitry Andric 
1495f757f3fSDimitry Andric } // end anonymous namespace
1505f757f3fSDimitry Andric 
1515f757f3fSDimitry Andric #define GET_GLOBALISEL_IMPL
1525f757f3fSDimitry Andric #include "X86GenGlobalISel.inc"
1535f757f3fSDimitry Andric #undef GET_GLOBALISEL_IMPL
1545f757f3fSDimitry Andric 
1555f757f3fSDimitry Andric X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
1565f757f3fSDimitry Andric                                                const X86Subtarget &STI,
1575f757f3fSDimitry Andric                                                const X86RegisterBankInfo &RBI)
1585f757f3fSDimitry Andric     : TM(TM), STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()),
1595f757f3fSDimitry Andric       RBI(RBI),
1605f757f3fSDimitry Andric #define GET_GLOBALISEL_PREDICATES_INIT
1615f757f3fSDimitry Andric #include "X86GenGlobalISel.inc"
1625f757f3fSDimitry Andric #undef GET_GLOBALISEL_PREDICATES_INIT
1635f757f3fSDimitry Andric #define GET_GLOBALISEL_TEMPORARIES_INIT
1645f757f3fSDimitry Andric #include "X86GenGlobalISel.inc"
1655f757f3fSDimitry Andric #undef GET_GLOBALISEL_TEMPORARIES_INIT
1665f757f3fSDimitry Andric {
1675f757f3fSDimitry Andric }
1685f757f3fSDimitry Andric 
1695f757f3fSDimitry Andric // FIXME: This should be target-independent, inferred from the types declared
1705f757f3fSDimitry Andric // for each class in the bank.
1715f757f3fSDimitry Andric const TargetRegisterClass *
1725f757f3fSDimitry Andric X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const {
1735f757f3fSDimitry Andric   if (RB.getID() == X86::GPRRegBankID) {
1745f757f3fSDimitry Andric     if (Ty.getSizeInBits() <= 8)
1755f757f3fSDimitry Andric       return &X86::GR8RegClass;
1765f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 16)
1775f757f3fSDimitry Andric       return &X86::GR16RegClass;
1785f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 32)
1795f757f3fSDimitry Andric       return &X86::GR32RegClass;
1805f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 64)
1815f757f3fSDimitry Andric       return &X86::GR64RegClass;
1825f757f3fSDimitry Andric   }
1835f757f3fSDimitry Andric   if (RB.getID() == X86::VECRRegBankID) {
1845f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 16)
1855f757f3fSDimitry Andric       return STI.hasAVX512() ? &X86::FR16XRegClass : &X86::FR16RegClass;
1865f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 32)
1875f757f3fSDimitry Andric       return STI.hasAVX512() ? &X86::FR32XRegClass : &X86::FR32RegClass;
1885f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 64)
1895f757f3fSDimitry Andric       return STI.hasAVX512() ? &X86::FR64XRegClass : &X86::FR64RegClass;
1905f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 128)
1915f757f3fSDimitry Andric       return STI.hasAVX512() ? &X86::VR128XRegClass : &X86::VR128RegClass;
1925f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 256)
1935f757f3fSDimitry Andric       return STI.hasAVX512() ? &X86::VR256XRegClass : &X86::VR256RegClass;
1945f757f3fSDimitry Andric     if (Ty.getSizeInBits() == 512)
1955f757f3fSDimitry Andric       return &X86::VR512RegClass;
1965f757f3fSDimitry Andric   }
1975f757f3fSDimitry Andric 
198*0fca6ea1SDimitry Andric   if (RB.getID() == X86::PSRRegBankID) {
199*0fca6ea1SDimitry Andric     if (Ty.getSizeInBits() == 80)
200*0fca6ea1SDimitry Andric       return &X86::RFP80RegClass;
201*0fca6ea1SDimitry Andric     if (Ty.getSizeInBits() == 64)
202*0fca6ea1SDimitry Andric       return &X86::RFP64RegClass;
203*0fca6ea1SDimitry Andric     if (Ty.getSizeInBits() == 32)
204*0fca6ea1SDimitry Andric       return &X86::RFP32RegClass;
205*0fca6ea1SDimitry Andric   }
206*0fca6ea1SDimitry Andric 
2075f757f3fSDimitry Andric   llvm_unreachable("Unknown RegBank!");
2085f757f3fSDimitry Andric }
2095f757f3fSDimitry Andric 
2105f757f3fSDimitry Andric const TargetRegisterClass *
2115f757f3fSDimitry Andric X86InstructionSelector::getRegClass(LLT Ty, unsigned Reg,
2125f757f3fSDimitry Andric                                     MachineRegisterInfo &MRI) const {
2135f757f3fSDimitry Andric   const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI);
2145f757f3fSDimitry Andric   return getRegClass(Ty, RegBank);
2155f757f3fSDimitry Andric }
2165f757f3fSDimitry Andric 
2175f757f3fSDimitry Andric static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
2185f757f3fSDimitry Andric   unsigned SubIdx = X86::NoSubRegister;
2195f757f3fSDimitry Andric   if (RC == &X86::GR32RegClass) {
2205f757f3fSDimitry Andric     SubIdx = X86::sub_32bit;
2215f757f3fSDimitry Andric   } else if (RC == &X86::GR16RegClass) {
2225f757f3fSDimitry Andric     SubIdx = X86::sub_16bit;
2235f757f3fSDimitry Andric   } else if (RC == &X86::GR8RegClass) {
2245f757f3fSDimitry Andric     SubIdx = X86::sub_8bit;
2255f757f3fSDimitry Andric   }
2265f757f3fSDimitry Andric 
2275f757f3fSDimitry Andric   return SubIdx;
2285f757f3fSDimitry Andric }
2295f757f3fSDimitry Andric 
2305f757f3fSDimitry Andric static const TargetRegisterClass *getRegClassFromGRPhysReg(Register Reg) {
2315f757f3fSDimitry Andric   assert(Reg.isPhysical());
2325f757f3fSDimitry Andric   if (X86::GR64RegClass.contains(Reg))
2335f757f3fSDimitry Andric     return &X86::GR64RegClass;
2345f757f3fSDimitry Andric   if (X86::GR32RegClass.contains(Reg))
2355f757f3fSDimitry Andric     return &X86::GR32RegClass;
2365f757f3fSDimitry Andric   if (X86::GR16RegClass.contains(Reg))
2375f757f3fSDimitry Andric     return &X86::GR16RegClass;
2385f757f3fSDimitry Andric   if (X86::GR8RegClass.contains(Reg))
2395f757f3fSDimitry Andric     return &X86::GR8RegClass;
2405f757f3fSDimitry Andric 
2415f757f3fSDimitry Andric   llvm_unreachable("Unknown RegClass for PhysReg!");
2425f757f3fSDimitry Andric }
2435f757f3fSDimitry Andric 
2445f757f3fSDimitry Andric // FIXME: We need some sort of API in RBI/TRI to allow generic code to
2455f757f3fSDimitry Andric // constrain operands of simple instructions given a TargetRegisterClass
2465f757f3fSDimitry Andric // and LLT
2475f757f3fSDimitry Andric bool X86InstructionSelector::selectDebugInstr(MachineInstr &I,
2485f757f3fSDimitry Andric                                               MachineRegisterInfo &MRI) const {
2495f757f3fSDimitry Andric   for (MachineOperand &MO : I.operands()) {
2505f757f3fSDimitry Andric     if (!MO.isReg())
2515f757f3fSDimitry Andric       continue;
2525f757f3fSDimitry Andric     Register Reg = MO.getReg();
2535f757f3fSDimitry Andric     if (!Reg)
2545f757f3fSDimitry Andric       continue;
2555f757f3fSDimitry Andric     if (Reg.isPhysical())
2565f757f3fSDimitry Andric       continue;
2575f757f3fSDimitry Andric     LLT Ty = MRI.getType(Reg);
2585f757f3fSDimitry Andric     const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);
2595f757f3fSDimitry Andric     const TargetRegisterClass *RC =
2605f757f3fSDimitry Andric         dyn_cast_if_present<const TargetRegisterClass *>(RegClassOrBank);
2615f757f3fSDimitry Andric     if (!RC) {
2625f757f3fSDimitry Andric       const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
2635f757f3fSDimitry Andric       RC = getRegClass(Ty, RB);
2645f757f3fSDimitry Andric       if (!RC) {
2655f757f3fSDimitry Andric         LLVM_DEBUG(
2665f757f3fSDimitry Andric             dbgs() << "Warning: DBG_VALUE operand has unexpected size/bank\n");
2675f757f3fSDimitry Andric         break;
2685f757f3fSDimitry Andric       }
2695f757f3fSDimitry Andric     }
2705f757f3fSDimitry Andric     RBI.constrainGenericRegister(Reg, *RC, MRI);
2715f757f3fSDimitry Andric   }
2725f757f3fSDimitry Andric 
2735f757f3fSDimitry Andric   return true;
2745f757f3fSDimitry Andric }
2755f757f3fSDimitry Andric 
2765f757f3fSDimitry Andric // Set X86 Opcode and constrain DestReg.
2775f757f3fSDimitry Andric bool X86InstructionSelector::selectCopy(MachineInstr &I,
2785f757f3fSDimitry Andric                                         MachineRegisterInfo &MRI) const {
2795f757f3fSDimitry Andric   Register DstReg = I.getOperand(0).getReg();
2805f757f3fSDimitry Andric   const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
2815f757f3fSDimitry Andric   const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
2825f757f3fSDimitry Andric 
2835f757f3fSDimitry Andric   Register SrcReg = I.getOperand(1).getReg();
2845f757f3fSDimitry Andric   const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
2855f757f3fSDimitry Andric   const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
2865f757f3fSDimitry Andric 
2875f757f3fSDimitry Andric   if (DstReg.isPhysical()) {
2885f757f3fSDimitry Andric     assert(I.isCopy() && "Generic operators do not allow physical registers");
2895f757f3fSDimitry Andric 
2905f757f3fSDimitry Andric     if (DstSize > SrcSize && SrcRegBank.getID() == X86::GPRRegBankID &&
2915f757f3fSDimitry Andric         DstRegBank.getID() == X86::GPRRegBankID) {
2925f757f3fSDimitry Andric 
2935f757f3fSDimitry Andric       const TargetRegisterClass *SrcRC =
2945f757f3fSDimitry Andric           getRegClass(MRI.getType(SrcReg), SrcRegBank);
2955f757f3fSDimitry Andric       const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg);
2965f757f3fSDimitry Andric 
2975f757f3fSDimitry Andric       if (SrcRC != DstRC) {
2985f757f3fSDimitry Andric         // This case can be generated by ABI lowering, performe anyext
2995f757f3fSDimitry Andric         Register ExtSrc = MRI.createVirtualRegister(DstRC);
3005f757f3fSDimitry Andric         BuildMI(*I.getParent(), I, I.getDebugLoc(),
3015f757f3fSDimitry Andric                 TII.get(TargetOpcode::SUBREG_TO_REG))
3025f757f3fSDimitry Andric             .addDef(ExtSrc)
3035f757f3fSDimitry Andric             .addImm(0)
3045f757f3fSDimitry Andric             .addReg(SrcReg)
3055f757f3fSDimitry Andric             .addImm(getSubRegIndex(SrcRC));
3065f757f3fSDimitry Andric 
3075f757f3fSDimitry Andric         I.getOperand(1).setReg(ExtSrc);
3085f757f3fSDimitry Andric       }
3095f757f3fSDimitry Andric     }
3105f757f3fSDimitry Andric 
3115f757f3fSDimitry Andric     return true;
3125f757f3fSDimitry Andric   }
3135f757f3fSDimitry Andric 
3145f757f3fSDimitry Andric   assert((!SrcReg.isPhysical() || I.isCopy()) &&
3155f757f3fSDimitry Andric          "No phys reg on generic operators");
3165f757f3fSDimitry Andric   assert((DstSize == SrcSize ||
3175f757f3fSDimitry Andric           // Copies are a mean to setup initial types, the number of
3185f757f3fSDimitry Andric           // bits may not exactly match.
3195f757f3fSDimitry Andric           (SrcReg.isPhysical() &&
3205f757f3fSDimitry Andric            DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
3215f757f3fSDimitry Andric          "Copy with different width?!");
3225f757f3fSDimitry Andric 
3235f757f3fSDimitry Andric   const TargetRegisterClass *DstRC =
3245f757f3fSDimitry Andric       getRegClass(MRI.getType(DstReg), DstRegBank);
3255f757f3fSDimitry Andric 
3265f757f3fSDimitry Andric   if (SrcRegBank.getID() == X86::GPRRegBankID &&
3275f757f3fSDimitry Andric       DstRegBank.getID() == X86::GPRRegBankID && SrcSize > DstSize &&
3285f757f3fSDimitry Andric       SrcReg.isPhysical()) {
3295f757f3fSDimitry Andric     // Change the physical register to performe truncate.
3305f757f3fSDimitry Andric 
3315f757f3fSDimitry Andric     const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
3325f757f3fSDimitry Andric 
3335f757f3fSDimitry Andric     if (DstRC != SrcRC) {
3345f757f3fSDimitry Andric       I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
3355f757f3fSDimitry Andric       I.getOperand(1).substPhysReg(SrcReg, TRI);
3365f757f3fSDimitry Andric     }
3375f757f3fSDimitry Andric   }
3385f757f3fSDimitry Andric 
3395f757f3fSDimitry Andric   // No need to constrain SrcReg. It will get constrained when
3405f757f3fSDimitry Andric   // we hit another of its use or its defs.
3415f757f3fSDimitry Andric   // Copies do not have constraints.
3425f757f3fSDimitry Andric   const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
3435f757f3fSDimitry Andric   if (!OldRC || !DstRC->hasSubClassEq(OldRC)) {
3445f757f3fSDimitry Andric     if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
3455f757f3fSDimitry Andric       LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
3465f757f3fSDimitry Andric                         << " operand\n");
3475f757f3fSDimitry Andric       return false;
3485f757f3fSDimitry Andric     }
3495f757f3fSDimitry Andric   }
3505f757f3fSDimitry Andric   I.setDesc(TII.get(X86::COPY));
3515f757f3fSDimitry Andric   return true;
3525f757f3fSDimitry Andric }
3535f757f3fSDimitry Andric 
3545f757f3fSDimitry Andric bool X86InstructionSelector::select(MachineInstr &I) {
3555f757f3fSDimitry Andric   assert(I.getParent() && "Instruction should be in a basic block!");
3565f757f3fSDimitry Andric   assert(I.getParent()->getParent() && "Instruction should be in a function!");
3575f757f3fSDimitry Andric 
3585f757f3fSDimitry Andric   MachineBasicBlock &MBB = *I.getParent();
3595f757f3fSDimitry Andric   MachineFunction &MF = *MBB.getParent();
3605f757f3fSDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
3615f757f3fSDimitry Andric 
3625f757f3fSDimitry Andric   unsigned Opcode = I.getOpcode();
3635f757f3fSDimitry Andric   if (!isPreISelGenericOpcode(Opcode)) {
3645f757f3fSDimitry Andric     // Certain non-generic instructions also need some special handling.
3655f757f3fSDimitry Andric 
3665f757f3fSDimitry Andric     if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
3675f757f3fSDimitry Andric       return false;
3685f757f3fSDimitry Andric 
3695f757f3fSDimitry Andric     if (I.isCopy())
3705f757f3fSDimitry Andric       return selectCopy(I, MRI);
3715f757f3fSDimitry Andric 
3725f757f3fSDimitry Andric     if (I.isDebugInstr())
3735f757f3fSDimitry Andric       return selectDebugInstr(I, MRI);
3745f757f3fSDimitry Andric 
3755f757f3fSDimitry Andric     return true;
3765f757f3fSDimitry Andric   }
3775f757f3fSDimitry Andric 
3785f757f3fSDimitry Andric   assert(I.getNumOperands() == I.getNumExplicitOperands() &&
3795f757f3fSDimitry Andric          "Generic instruction has unexpected implicit operands\n");
3805f757f3fSDimitry Andric 
3815f757f3fSDimitry Andric   if (selectImpl(I, *CoverageInfo))
3825f757f3fSDimitry Andric     return true;
3835f757f3fSDimitry Andric 
3845f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
3855f757f3fSDimitry Andric 
3865f757f3fSDimitry Andric   // TODO: This should be implemented by tblgen.
3875f757f3fSDimitry Andric   switch (I.getOpcode()) {
3885f757f3fSDimitry Andric   default:
3895f757f3fSDimitry Andric     return false;
3905f757f3fSDimitry Andric   case TargetOpcode::G_STORE:
3915f757f3fSDimitry Andric   case TargetOpcode::G_LOAD:
3925f757f3fSDimitry Andric     return selectLoadStoreOp(I, MRI, MF);
3935f757f3fSDimitry Andric   case TargetOpcode::G_PTR_ADD:
3945f757f3fSDimitry Andric   case TargetOpcode::G_FRAME_INDEX:
3955f757f3fSDimitry Andric     return selectFrameIndexOrGep(I, MRI, MF);
3965f757f3fSDimitry Andric   case TargetOpcode::G_GLOBAL_VALUE:
3975f757f3fSDimitry Andric     return selectGlobalValue(I, MRI, MF);
3985f757f3fSDimitry Andric   case TargetOpcode::G_CONSTANT:
3995f757f3fSDimitry Andric     return selectConstant(I, MRI, MF);
4005f757f3fSDimitry Andric   case TargetOpcode::G_FCONSTANT:
4015f757f3fSDimitry Andric     return materializeFP(I, MRI, MF);
4025f757f3fSDimitry Andric   case TargetOpcode::G_PTRTOINT:
4035f757f3fSDimitry Andric   case TargetOpcode::G_TRUNC:
4045f757f3fSDimitry Andric     return selectTruncOrPtrToInt(I, MRI, MF);
4055f757f3fSDimitry Andric   case TargetOpcode::G_INTTOPTR:
4065f757f3fSDimitry Andric     return selectCopy(I, MRI);
4075f757f3fSDimitry Andric   case TargetOpcode::G_ZEXT:
4085f757f3fSDimitry Andric     return selectZext(I, MRI, MF);
4095f757f3fSDimitry Andric   case TargetOpcode::G_ANYEXT:
4105f757f3fSDimitry Andric     return selectAnyext(I, MRI, MF);
4115f757f3fSDimitry Andric   case TargetOpcode::G_ICMP:
4125f757f3fSDimitry Andric     return selectCmp(I, MRI, MF);
4135f757f3fSDimitry Andric   case TargetOpcode::G_FCMP:
4145f757f3fSDimitry Andric     return selectFCmp(I, MRI, MF);
4155f757f3fSDimitry Andric   case TargetOpcode::G_UADDE:
4165f757f3fSDimitry Andric   case TargetOpcode::G_UADDO:
4175f757f3fSDimitry Andric   case TargetOpcode::G_USUBE:
4185f757f3fSDimitry Andric   case TargetOpcode::G_USUBO:
4195f757f3fSDimitry Andric     return selectUAddSub(I, MRI, MF);
4205f757f3fSDimitry Andric   case TargetOpcode::G_UNMERGE_VALUES:
4215f757f3fSDimitry Andric     return selectUnmergeValues(I, MRI, MF);
4225f757f3fSDimitry Andric   case TargetOpcode::G_MERGE_VALUES:
4235f757f3fSDimitry Andric   case TargetOpcode::G_CONCAT_VECTORS:
4245f757f3fSDimitry Andric     return selectMergeValues(I, MRI, MF);
4255f757f3fSDimitry Andric   case TargetOpcode::G_EXTRACT:
4265f757f3fSDimitry Andric     return selectExtract(I, MRI, MF);
4275f757f3fSDimitry Andric   case TargetOpcode::G_INSERT:
4285f757f3fSDimitry Andric     return selectInsert(I, MRI, MF);
4295f757f3fSDimitry Andric   case TargetOpcode::G_BRCOND:
4305f757f3fSDimitry Andric     return selectCondBranch(I, MRI, MF);
4315f757f3fSDimitry Andric   case TargetOpcode::G_IMPLICIT_DEF:
4325f757f3fSDimitry Andric   case TargetOpcode::G_PHI:
4335f757f3fSDimitry Andric     return selectImplicitDefOrPHI(I, MRI);
4345f757f3fSDimitry Andric   case TargetOpcode::G_MUL:
4355f757f3fSDimitry Andric   case TargetOpcode::G_SMULH:
4365f757f3fSDimitry Andric   case TargetOpcode::G_UMULH:
4375f757f3fSDimitry Andric   case TargetOpcode::G_SDIV:
4385f757f3fSDimitry Andric   case TargetOpcode::G_UDIV:
4395f757f3fSDimitry Andric   case TargetOpcode::G_SREM:
4405f757f3fSDimitry Andric   case TargetOpcode::G_UREM:
4415f757f3fSDimitry Andric     return selectMulDivRem(I, MRI, MF);
4425f757f3fSDimitry Andric   case TargetOpcode::G_SELECT:
4435f757f3fSDimitry Andric     return selectSelect(I, MRI, MF);
4445f757f3fSDimitry Andric   }
4455f757f3fSDimitry Andric 
4465f757f3fSDimitry Andric   return false;
4475f757f3fSDimitry Andric }
4485f757f3fSDimitry Andric 
4495f757f3fSDimitry Andric unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
4505f757f3fSDimitry Andric                                                 const RegisterBank &RB,
4515f757f3fSDimitry Andric                                                 unsigned Opc,
4525f757f3fSDimitry Andric                                                 Align Alignment) const {
4535f757f3fSDimitry Andric   bool Isload = (Opc == TargetOpcode::G_LOAD);
4545f757f3fSDimitry Andric   bool HasAVX = STI.hasAVX();
4555f757f3fSDimitry Andric   bool HasAVX512 = STI.hasAVX512();
4565f757f3fSDimitry Andric   bool HasVLX = STI.hasVLX();
4575f757f3fSDimitry Andric 
4585f757f3fSDimitry Andric   if (Ty == LLT::scalar(8)) {
4595f757f3fSDimitry Andric     if (X86::GPRRegBankID == RB.getID())
4605f757f3fSDimitry Andric       return Isload ? X86::MOV8rm : X86::MOV8mr;
4615f757f3fSDimitry Andric   } else if (Ty == LLT::scalar(16)) {
4625f757f3fSDimitry Andric     if (X86::GPRRegBankID == RB.getID())
4635f757f3fSDimitry Andric       return Isload ? X86::MOV16rm : X86::MOV16mr;
4645f757f3fSDimitry Andric   } else if (Ty == LLT::scalar(32) || Ty == LLT::pointer(0, 32)) {
4655f757f3fSDimitry Andric     if (X86::GPRRegBankID == RB.getID())
4665f757f3fSDimitry Andric       return Isload ? X86::MOV32rm : X86::MOV32mr;
4675f757f3fSDimitry Andric     if (X86::VECRRegBankID == RB.getID())
4685f757f3fSDimitry Andric       return Isload ? (HasAVX512 ? X86::VMOVSSZrm_alt :
4695f757f3fSDimitry Andric                        HasAVX    ? X86::VMOVSSrm_alt :
4705f757f3fSDimitry Andric                                    X86::MOVSSrm_alt)
4715f757f3fSDimitry Andric                     : (HasAVX512 ? X86::VMOVSSZmr :
4725f757f3fSDimitry Andric                        HasAVX    ? X86::VMOVSSmr :
4735f757f3fSDimitry Andric                                    X86::MOVSSmr);
474*0fca6ea1SDimitry Andric     if (X86::PSRRegBankID == RB.getID())
475*0fca6ea1SDimitry Andric       return Isload ? X86::LD_Fp32m : X86::ST_Fp32m;
4765f757f3fSDimitry Andric   } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) {
4775f757f3fSDimitry Andric     if (X86::GPRRegBankID == RB.getID())
4785f757f3fSDimitry Andric       return Isload ? X86::MOV64rm : X86::MOV64mr;
4795f757f3fSDimitry Andric     if (X86::VECRRegBankID == RB.getID())
4805f757f3fSDimitry Andric       return Isload ? (HasAVX512 ? X86::VMOVSDZrm_alt :
4815f757f3fSDimitry Andric                        HasAVX    ? X86::VMOVSDrm_alt :
4825f757f3fSDimitry Andric                                    X86::MOVSDrm_alt)
4835f757f3fSDimitry Andric                     : (HasAVX512 ? X86::VMOVSDZmr :
4845f757f3fSDimitry Andric                        HasAVX    ? X86::VMOVSDmr :
4855f757f3fSDimitry Andric                                    X86::MOVSDmr);
486*0fca6ea1SDimitry Andric     if (X86::PSRRegBankID == RB.getID())
487*0fca6ea1SDimitry Andric       return Isload ? X86::LD_Fp64m : X86::ST_Fp64m;
488*0fca6ea1SDimitry Andric   } else if (Ty == LLT::scalar(80)) {
489*0fca6ea1SDimitry Andric     return Isload ? X86::LD_Fp80m : X86::ST_FpP80m;
4905f757f3fSDimitry Andric   } else if (Ty.isVector() && Ty.getSizeInBits() == 128) {
4915f757f3fSDimitry Andric     if (Alignment >= Align(16))
4925f757f3fSDimitry Andric       return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
4935f757f3fSDimitry Andric                               : HasAVX512
4945f757f3fSDimitry Andric                                     ? X86::VMOVAPSZ128rm_NOVLX
4955f757f3fSDimitry Andric                                     : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
4965f757f3fSDimitry Andric                     : (HasVLX ? X86::VMOVAPSZ128mr
4975f757f3fSDimitry Andric                               : HasAVX512
4985f757f3fSDimitry Andric                                     ? X86::VMOVAPSZ128mr_NOVLX
4995f757f3fSDimitry Andric                                     : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr);
5005f757f3fSDimitry Andric     else
5015f757f3fSDimitry Andric       return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
5025f757f3fSDimitry Andric                               : HasAVX512
5035f757f3fSDimitry Andric                                     ? X86::VMOVUPSZ128rm_NOVLX
5045f757f3fSDimitry Andric                                     : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
5055f757f3fSDimitry Andric                     : (HasVLX ? X86::VMOVUPSZ128mr
5065f757f3fSDimitry Andric                               : HasAVX512
5075f757f3fSDimitry Andric                                     ? X86::VMOVUPSZ128mr_NOVLX
5085f757f3fSDimitry Andric                                     : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
5095f757f3fSDimitry Andric   } else if (Ty.isVector() && Ty.getSizeInBits() == 256) {
5105f757f3fSDimitry Andric     if (Alignment >= Align(32))
5115f757f3fSDimitry Andric       return Isload ? (HasVLX ? X86::VMOVAPSZ256rm
5125f757f3fSDimitry Andric                               : HasAVX512 ? X86::VMOVAPSZ256rm_NOVLX
5135f757f3fSDimitry Andric                                           : X86::VMOVAPSYrm)
5145f757f3fSDimitry Andric                     : (HasVLX ? X86::VMOVAPSZ256mr
5155f757f3fSDimitry Andric                               : HasAVX512 ? X86::VMOVAPSZ256mr_NOVLX
5165f757f3fSDimitry Andric                                           : X86::VMOVAPSYmr);
5175f757f3fSDimitry Andric     else
5185f757f3fSDimitry Andric       return Isload ? (HasVLX ? X86::VMOVUPSZ256rm
5195f757f3fSDimitry Andric                               : HasAVX512 ? X86::VMOVUPSZ256rm_NOVLX
5205f757f3fSDimitry Andric                                           : X86::VMOVUPSYrm)
5215f757f3fSDimitry Andric                     : (HasVLX ? X86::VMOVUPSZ256mr
5225f757f3fSDimitry Andric                               : HasAVX512 ? X86::VMOVUPSZ256mr_NOVLX
5235f757f3fSDimitry Andric                                           : X86::VMOVUPSYmr);
5245f757f3fSDimitry Andric   } else if (Ty.isVector() && Ty.getSizeInBits() == 512) {
5255f757f3fSDimitry Andric     if (Alignment >= Align(64))
5265f757f3fSDimitry Andric       return Isload ? X86::VMOVAPSZrm : X86::VMOVAPSZmr;
5275f757f3fSDimitry Andric     else
5285f757f3fSDimitry Andric       return Isload ? X86::VMOVUPSZrm : X86::VMOVUPSZmr;
5295f757f3fSDimitry Andric   }
5305f757f3fSDimitry Andric   return Opc;
5315f757f3fSDimitry Andric }
5325f757f3fSDimitry Andric 
5335f757f3fSDimitry Andric // Fill in an address from the given instruction.
5345f757f3fSDimitry Andric static void X86SelectAddress(const MachineInstr &I,
5355f757f3fSDimitry Andric                              const MachineRegisterInfo &MRI,
5365f757f3fSDimitry Andric                              X86AddressMode &AM) {
5375f757f3fSDimitry Andric   assert(I.getOperand(0).isReg() && "unsupported opperand.");
5385f757f3fSDimitry Andric   assert(MRI.getType(I.getOperand(0).getReg()).isPointer() &&
5395f757f3fSDimitry Andric          "unsupported type.");
5405f757f3fSDimitry Andric 
5415f757f3fSDimitry Andric   if (I.getOpcode() == TargetOpcode::G_PTR_ADD) {
5425f757f3fSDimitry Andric     if (auto COff = getIConstantVRegSExtVal(I.getOperand(2).getReg(), MRI)) {
5435f757f3fSDimitry Andric       int64_t Imm = *COff;
5445f757f3fSDimitry Andric       if (isInt<32>(Imm)) { // Check for displacement overflow.
5455f757f3fSDimitry Andric         AM.Disp = static_cast<int32_t>(Imm);
5465f757f3fSDimitry Andric         AM.Base.Reg = I.getOperand(1).getReg();
5475f757f3fSDimitry Andric         return;
5485f757f3fSDimitry Andric       }
5495f757f3fSDimitry Andric     }
5505f757f3fSDimitry Andric   } else if (I.getOpcode() == TargetOpcode::G_FRAME_INDEX) {
5515f757f3fSDimitry Andric     AM.Base.FrameIndex = I.getOperand(1).getIndex();
5525f757f3fSDimitry Andric     AM.BaseType = X86AddressMode::FrameIndexBase;
5535f757f3fSDimitry Andric     return;
5545f757f3fSDimitry Andric   }
5555f757f3fSDimitry Andric 
5565f757f3fSDimitry Andric   // Default behavior.
5575f757f3fSDimitry Andric   AM.Base.Reg = I.getOperand(0).getReg();
5585f757f3fSDimitry Andric }
5595f757f3fSDimitry Andric 
5605f757f3fSDimitry Andric bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
5615f757f3fSDimitry Andric                                                MachineRegisterInfo &MRI,
5625f757f3fSDimitry Andric                                                MachineFunction &MF) const {
5635f757f3fSDimitry Andric   unsigned Opc = I.getOpcode();
5645f757f3fSDimitry Andric 
5655f757f3fSDimitry Andric   assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
566*0fca6ea1SDimitry Andric          "Only G_STORE and G_LOAD are expected for selection");
5675f757f3fSDimitry Andric 
5685f757f3fSDimitry Andric   const Register DefReg = I.getOperand(0).getReg();
5695f757f3fSDimitry Andric   LLT Ty = MRI.getType(DefReg);
5705f757f3fSDimitry Andric   const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
5715f757f3fSDimitry Andric 
5725f757f3fSDimitry Andric   assert(I.hasOneMemOperand());
5735f757f3fSDimitry Andric   auto &MemOp = **I.memoperands_begin();
5745f757f3fSDimitry Andric   if (MemOp.isAtomic()) {
5755f757f3fSDimitry Andric     // Note: for unordered operations, we rely on the fact the appropriate MMO
5765f757f3fSDimitry Andric     // is already on the instruction we're mutating, and thus we don't need to
5775f757f3fSDimitry Andric     // make any changes.  So long as we select an opcode which is capable of
5785f757f3fSDimitry Andric     // loading or storing the appropriate size atomically, the rest of the
5795f757f3fSDimitry Andric     // backend is required to respect the MMO state.
5805f757f3fSDimitry Andric     if (!MemOp.isUnordered()) {
5815f757f3fSDimitry Andric       LLVM_DEBUG(dbgs() << "Atomic ordering not supported yet\n");
5825f757f3fSDimitry Andric       return false;
5835f757f3fSDimitry Andric     }
5845f757f3fSDimitry Andric     if (MemOp.getAlign() < Ty.getSizeInBits() / 8) {
5855f757f3fSDimitry Andric       LLVM_DEBUG(dbgs() << "Unaligned atomics not supported yet\n");
5865f757f3fSDimitry Andric       return false;
5875f757f3fSDimitry Andric     }
5885f757f3fSDimitry Andric   }
5895f757f3fSDimitry Andric 
5905f757f3fSDimitry Andric   unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlign());
5915f757f3fSDimitry Andric   if (NewOpc == Opc)
5925f757f3fSDimitry Andric     return false;
5935f757f3fSDimitry Andric 
5945f757f3fSDimitry Andric   I.setDesc(TII.get(NewOpc));
5955f757f3fSDimitry Andric   MachineInstrBuilder MIB(MF, I);
596*0fca6ea1SDimitry Andric   const MachineInstr *Ptr = MRI.getVRegDef(I.getOperand(1).getReg());
597*0fca6ea1SDimitry Andric 
598*0fca6ea1SDimitry Andric   if (Ptr->getOpcode() == TargetOpcode::G_CONSTANT_POOL) {
599*0fca6ea1SDimitry Andric     assert(Opc == TargetOpcode::G_LOAD &&
600*0fca6ea1SDimitry Andric            "Only G_LOAD from constant pool is expected");
601*0fca6ea1SDimitry Andric     // TODO: Need a separate move for Large model
602*0fca6ea1SDimitry Andric     if (TM.getCodeModel() == CodeModel::Large)
603*0fca6ea1SDimitry Andric       return false;
604*0fca6ea1SDimitry Andric 
605*0fca6ea1SDimitry Andric     unsigned char OpFlag = STI.classifyLocalReference(nullptr);
606*0fca6ea1SDimitry Andric     unsigned PICBase = 0;
607*0fca6ea1SDimitry Andric     if (OpFlag == X86II::MO_GOTOFF)
608*0fca6ea1SDimitry Andric       PICBase = TII.getGlobalBaseReg(&MF);
609*0fca6ea1SDimitry Andric     else if (STI.is64Bit())
610*0fca6ea1SDimitry Andric       PICBase = X86::RIP;
611*0fca6ea1SDimitry Andric 
612*0fca6ea1SDimitry Andric     I.removeOperand(1);
613*0fca6ea1SDimitry Andric     addConstantPoolReference(MIB, Ptr->getOperand(1).getIndex(), PICBase,
614*0fca6ea1SDimitry Andric                              OpFlag);
615*0fca6ea1SDimitry Andric     return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
616*0fca6ea1SDimitry Andric   }
617*0fca6ea1SDimitry Andric 
618*0fca6ea1SDimitry Andric   X86AddressMode AM;
619*0fca6ea1SDimitry Andric   X86SelectAddress(*Ptr, MRI, AM);
6205f757f3fSDimitry Andric   if (Opc == TargetOpcode::G_LOAD) {
6215f757f3fSDimitry Andric     I.removeOperand(1);
6225f757f3fSDimitry Andric     addFullAddress(MIB, AM);
6235f757f3fSDimitry Andric   } else {
6245f757f3fSDimitry Andric     // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
6255f757f3fSDimitry Andric     I.removeOperand(1);
6265f757f3fSDimitry Andric     I.removeOperand(0);
6275f757f3fSDimitry Andric     addFullAddress(MIB, AM).addUse(DefReg);
6285f757f3fSDimitry Andric   }
629*0fca6ea1SDimitry Andric   bool Constrained = constrainSelectedInstRegOperands(I, TII, TRI, RBI);
630*0fca6ea1SDimitry Andric   I.addImplicitDefUseOperands(MF);
631*0fca6ea1SDimitry Andric   return Constrained;
6325f757f3fSDimitry Andric }
6335f757f3fSDimitry Andric 
6345f757f3fSDimitry Andric static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) {
6355f757f3fSDimitry Andric   if (Ty == LLT::pointer(0, 64))
6365f757f3fSDimitry Andric     return X86::LEA64r;
6375f757f3fSDimitry Andric   else if (Ty == LLT::pointer(0, 32))
6385f757f3fSDimitry Andric     return STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
6395f757f3fSDimitry Andric   else
6405f757f3fSDimitry Andric     llvm_unreachable("Can't get LEA opcode. Unsupported type.");
6415f757f3fSDimitry Andric }
6425f757f3fSDimitry Andric 
6435f757f3fSDimitry Andric bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
6445f757f3fSDimitry Andric                                                    MachineRegisterInfo &MRI,
6455f757f3fSDimitry Andric                                                    MachineFunction &MF) const {
6465f757f3fSDimitry Andric   unsigned Opc = I.getOpcode();
6475f757f3fSDimitry Andric 
6485f757f3fSDimitry Andric   assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_PTR_ADD) &&
6495f757f3fSDimitry Andric          "unexpected instruction");
6505f757f3fSDimitry Andric 
6515f757f3fSDimitry Andric   const Register DefReg = I.getOperand(0).getReg();
6525f757f3fSDimitry Andric   LLT Ty = MRI.getType(DefReg);
6535f757f3fSDimitry Andric 
6545f757f3fSDimitry Andric   // Use LEA to calculate frame index and GEP
6555f757f3fSDimitry Andric   unsigned NewOpc = getLeaOP(Ty, STI);
6565f757f3fSDimitry Andric   I.setDesc(TII.get(NewOpc));
6575f757f3fSDimitry Andric   MachineInstrBuilder MIB(MF, I);
6585f757f3fSDimitry Andric 
6595f757f3fSDimitry Andric   if (Opc == TargetOpcode::G_FRAME_INDEX) {
6605f757f3fSDimitry Andric     addOffset(MIB, 0);
6615f757f3fSDimitry Andric   } else {
6625f757f3fSDimitry Andric     MachineOperand &InxOp = I.getOperand(2);
6635f757f3fSDimitry Andric     I.addOperand(InxOp);        // set IndexReg
6645f757f3fSDimitry Andric     InxOp.ChangeToImmediate(1); // set Scale
6655f757f3fSDimitry Andric     MIB.addImm(0).addReg(0);
6665f757f3fSDimitry Andric   }
6675f757f3fSDimitry Andric 
6685f757f3fSDimitry Andric   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
6695f757f3fSDimitry Andric }
6705f757f3fSDimitry Andric 
6715f757f3fSDimitry Andric bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
6725f757f3fSDimitry Andric                                                MachineRegisterInfo &MRI,
6735f757f3fSDimitry Andric                                                MachineFunction &MF) const {
6745f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
6755f757f3fSDimitry Andric          "unexpected instruction");
6765f757f3fSDimitry Andric 
6775f757f3fSDimitry Andric   auto GV = I.getOperand(1).getGlobal();
6785f757f3fSDimitry Andric   if (GV->isThreadLocal()) {
6795f757f3fSDimitry Andric     return false; // TODO: we don't support TLS yet.
6805f757f3fSDimitry Andric   }
6815f757f3fSDimitry Andric 
6825f757f3fSDimitry Andric   // Can't handle alternate code models yet.
6835f757f3fSDimitry Andric   if (TM.getCodeModel() != CodeModel::Small)
6845f757f3fSDimitry Andric     return false;
6855f757f3fSDimitry Andric 
6865f757f3fSDimitry Andric   X86AddressMode AM;
6875f757f3fSDimitry Andric   AM.GV = GV;
6885f757f3fSDimitry Andric   AM.GVOpFlags = STI.classifyGlobalReference(GV);
6895f757f3fSDimitry Andric 
6905f757f3fSDimitry Andric   // TODO: The ABI requires an extra load. not supported yet.
6915f757f3fSDimitry Andric   if (isGlobalStubReference(AM.GVOpFlags))
6925f757f3fSDimitry Andric     return false;
6935f757f3fSDimitry Andric 
6945f757f3fSDimitry Andric   // TODO: This reference is relative to the pic base. not supported yet.
6955f757f3fSDimitry Andric   if (isGlobalRelativeToPICBase(AM.GVOpFlags))
6965f757f3fSDimitry Andric     return false;
6975f757f3fSDimitry Andric 
6985f757f3fSDimitry Andric   if (STI.isPICStyleRIPRel()) {
6995f757f3fSDimitry Andric     // Use rip-relative addressing.
7005f757f3fSDimitry Andric     assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
7015f757f3fSDimitry Andric     AM.Base.Reg = X86::RIP;
7025f757f3fSDimitry Andric   }
7035f757f3fSDimitry Andric 
7045f757f3fSDimitry Andric   const Register DefReg = I.getOperand(0).getReg();
7055f757f3fSDimitry Andric   LLT Ty = MRI.getType(DefReg);
7065f757f3fSDimitry Andric   unsigned NewOpc = getLeaOP(Ty, STI);
7075f757f3fSDimitry Andric 
7085f757f3fSDimitry Andric   I.setDesc(TII.get(NewOpc));
7095f757f3fSDimitry Andric   MachineInstrBuilder MIB(MF, I);
7105f757f3fSDimitry Andric 
7115f757f3fSDimitry Andric   I.removeOperand(1);
7125f757f3fSDimitry Andric   addFullAddress(MIB, AM);
7135f757f3fSDimitry Andric 
7145f757f3fSDimitry Andric   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
7155f757f3fSDimitry Andric }
7165f757f3fSDimitry Andric 
7175f757f3fSDimitry Andric bool X86InstructionSelector::selectConstant(MachineInstr &I,
7185f757f3fSDimitry Andric                                             MachineRegisterInfo &MRI,
7195f757f3fSDimitry Andric                                             MachineFunction &MF) const {
7205f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_CONSTANT) &&
7215f757f3fSDimitry Andric          "unexpected instruction");
7225f757f3fSDimitry Andric 
7235f757f3fSDimitry Andric   const Register DefReg = I.getOperand(0).getReg();
7245f757f3fSDimitry Andric   LLT Ty = MRI.getType(DefReg);
7255f757f3fSDimitry Andric 
7265f757f3fSDimitry Andric   if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID)
7275f757f3fSDimitry Andric     return false;
7285f757f3fSDimitry Andric 
7295f757f3fSDimitry Andric   uint64_t Val = 0;
7305f757f3fSDimitry Andric   if (I.getOperand(1).isCImm()) {
7315f757f3fSDimitry Andric     Val = I.getOperand(1).getCImm()->getZExtValue();
7325f757f3fSDimitry Andric     I.getOperand(1).ChangeToImmediate(Val);
7335f757f3fSDimitry Andric   } else if (I.getOperand(1).isImm()) {
7345f757f3fSDimitry Andric     Val = I.getOperand(1).getImm();
7355f757f3fSDimitry Andric   } else
7365f757f3fSDimitry Andric     llvm_unreachable("Unsupported operand type.");
7375f757f3fSDimitry Andric 
7385f757f3fSDimitry Andric   unsigned NewOpc;
7395f757f3fSDimitry Andric   switch (Ty.getSizeInBits()) {
7405f757f3fSDimitry Andric   case 8:
7415f757f3fSDimitry Andric     NewOpc = X86::MOV8ri;
7425f757f3fSDimitry Andric     break;
7435f757f3fSDimitry Andric   case 16:
7445f757f3fSDimitry Andric     NewOpc = X86::MOV16ri;
7455f757f3fSDimitry Andric     break;
7465f757f3fSDimitry Andric   case 32:
7475f757f3fSDimitry Andric     NewOpc = X86::MOV32ri;
7485f757f3fSDimitry Andric     break;
7495f757f3fSDimitry Andric   case 64:
7505f757f3fSDimitry Andric     // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
7515f757f3fSDimitry Andric     if (isInt<32>(Val))
7525f757f3fSDimitry Andric       NewOpc = X86::MOV64ri32;
7535f757f3fSDimitry Andric     else
7545f757f3fSDimitry Andric       NewOpc = X86::MOV64ri;
7555f757f3fSDimitry Andric     break;
7565f757f3fSDimitry Andric   default:
7575f757f3fSDimitry Andric     llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
7585f757f3fSDimitry Andric   }
7595f757f3fSDimitry Andric 
7605f757f3fSDimitry Andric   I.setDesc(TII.get(NewOpc));
7615f757f3fSDimitry Andric   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
7625f757f3fSDimitry Andric }
7635f757f3fSDimitry Andric 
7645f757f3fSDimitry Andric // Helper function for selectTruncOrPtrToInt and selectAnyext.
7655f757f3fSDimitry Andric // Returns true if DstRC lives on a floating register class and
7665f757f3fSDimitry Andric // SrcRC lives on a 128-bit vector class.
7675f757f3fSDimitry Andric static bool canTurnIntoCOPY(const TargetRegisterClass *DstRC,
7685f757f3fSDimitry Andric                             const TargetRegisterClass *SrcRC) {
7695f757f3fSDimitry Andric   return (DstRC == &X86::FR32RegClass || DstRC == &X86::FR32XRegClass ||
7705f757f3fSDimitry Andric           DstRC == &X86::FR64RegClass || DstRC == &X86::FR64XRegClass) &&
7715f757f3fSDimitry Andric          (SrcRC == &X86::VR128RegClass || SrcRC == &X86::VR128XRegClass);
7725f757f3fSDimitry Andric }
7735f757f3fSDimitry Andric 
7745f757f3fSDimitry Andric bool X86InstructionSelector::selectTurnIntoCOPY(
7755f757f3fSDimitry Andric     MachineInstr &I, MachineRegisterInfo &MRI, const unsigned DstReg,
7765f757f3fSDimitry Andric     const TargetRegisterClass *DstRC, const unsigned SrcReg,
7775f757f3fSDimitry Andric     const TargetRegisterClass *SrcRC) const {
7785f757f3fSDimitry Andric 
7795f757f3fSDimitry Andric   if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
7805f757f3fSDimitry Andric       !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
7815f757f3fSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
7825f757f3fSDimitry Andric                       << " operand\n");
7835f757f3fSDimitry Andric     return false;
7845f757f3fSDimitry Andric   }
7855f757f3fSDimitry Andric   I.setDesc(TII.get(X86::COPY));
7865f757f3fSDimitry Andric   return true;
7875f757f3fSDimitry Andric }
7885f757f3fSDimitry Andric 
7895f757f3fSDimitry Andric bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &I,
7905f757f3fSDimitry Andric                                                    MachineRegisterInfo &MRI,
7915f757f3fSDimitry Andric                                                    MachineFunction &MF) const {
7925f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_TRUNC ||
7935f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_PTRTOINT) &&
7945f757f3fSDimitry Andric          "unexpected instruction");
7955f757f3fSDimitry Andric 
7965f757f3fSDimitry Andric   const Register DstReg = I.getOperand(0).getReg();
7975f757f3fSDimitry Andric   const Register SrcReg = I.getOperand(1).getReg();
7985f757f3fSDimitry Andric 
7995f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
8005f757f3fSDimitry Andric   const LLT SrcTy = MRI.getType(SrcReg);
8015f757f3fSDimitry Andric 
8025f757f3fSDimitry Andric   const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
8035f757f3fSDimitry Andric   const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
8045f757f3fSDimitry Andric 
8055f757f3fSDimitry Andric   if (DstRB.getID() != SrcRB.getID()) {
8065f757f3fSDimitry Andric     LLVM_DEBUG(dbgs() << TII.getName(I.getOpcode())
8075f757f3fSDimitry Andric                       << " input/output on different banks\n");
8085f757f3fSDimitry Andric     return false;
8095f757f3fSDimitry Andric   }
8105f757f3fSDimitry Andric 
8115f757f3fSDimitry Andric   const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
8125f757f3fSDimitry Andric   const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
8135f757f3fSDimitry Andric 
8145f757f3fSDimitry Andric   if (!DstRC || !SrcRC)
8155f757f3fSDimitry Andric     return false;
8165f757f3fSDimitry Andric 
8175f757f3fSDimitry Andric   // If that's truncation of the value that lives on the vector class and goes
8185f757f3fSDimitry Andric   // into the floating class, just replace it with copy, as we are able to
8195f757f3fSDimitry Andric   // select it as a regular move.
8205f757f3fSDimitry Andric   if (canTurnIntoCOPY(DstRC, SrcRC))
8215f757f3fSDimitry Andric     return selectTurnIntoCOPY(I, MRI, DstReg, DstRC, SrcReg, SrcRC);
8225f757f3fSDimitry Andric 
8235f757f3fSDimitry Andric   if (DstRB.getID() != X86::GPRRegBankID)
8245f757f3fSDimitry Andric     return false;
8255f757f3fSDimitry Andric 
8265f757f3fSDimitry Andric   unsigned SubIdx;
8275f757f3fSDimitry Andric   if (DstRC == SrcRC) {
8285f757f3fSDimitry Andric     // Nothing to be done
8295f757f3fSDimitry Andric     SubIdx = X86::NoSubRegister;
8305f757f3fSDimitry Andric   } else if (DstRC == &X86::GR32RegClass) {
8315f757f3fSDimitry Andric     SubIdx = X86::sub_32bit;
8325f757f3fSDimitry Andric   } else if (DstRC == &X86::GR16RegClass) {
8335f757f3fSDimitry Andric     SubIdx = X86::sub_16bit;
8345f757f3fSDimitry Andric   } else if (DstRC == &X86::GR8RegClass) {
8355f757f3fSDimitry Andric     SubIdx = X86::sub_8bit;
8365f757f3fSDimitry Andric   } else {
8375f757f3fSDimitry Andric     return false;
8385f757f3fSDimitry Andric   }
8395f757f3fSDimitry Andric 
8405f757f3fSDimitry Andric   SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
8415f757f3fSDimitry Andric 
8425f757f3fSDimitry Andric   if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
8435f757f3fSDimitry Andric       !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
8445f757f3fSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
8455f757f3fSDimitry Andric                       << "\n");
8465f757f3fSDimitry Andric     return false;
8475f757f3fSDimitry Andric   }
8485f757f3fSDimitry Andric 
8495f757f3fSDimitry Andric   I.getOperand(1).setSubReg(SubIdx);
8505f757f3fSDimitry Andric 
8515f757f3fSDimitry Andric   I.setDesc(TII.get(X86::COPY));
8525f757f3fSDimitry Andric   return true;
8535f757f3fSDimitry Andric }
8545f757f3fSDimitry Andric 
8555f757f3fSDimitry Andric bool X86InstructionSelector::selectZext(MachineInstr &I,
8565f757f3fSDimitry Andric                                         MachineRegisterInfo &MRI,
8575f757f3fSDimitry Andric                                         MachineFunction &MF) const {
8585f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction");
8595f757f3fSDimitry Andric 
8605f757f3fSDimitry Andric   const Register DstReg = I.getOperand(0).getReg();
8615f757f3fSDimitry Andric   const Register SrcReg = I.getOperand(1).getReg();
8625f757f3fSDimitry Andric 
8635f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
8645f757f3fSDimitry Andric   const LLT SrcTy = MRI.getType(SrcReg);
8655f757f3fSDimitry Andric 
8665f757f3fSDimitry Andric   assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(16)) &&
8675f757f3fSDimitry Andric          "8=>16 Zext is handled by tablegen");
8685f757f3fSDimitry Andric   assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(32)) &&
8695f757f3fSDimitry Andric          "8=>32 Zext is handled by tablegen");
8705f757f3fSDimitry Andric   assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(32)) &&
8715f757f3fSDimitry Andric          "16=>32 Zext is handled by tablegen");
8725f757f3fSDimitry Andric   assert(!(SrcTy == LLT::scalar(8) && DstTy == LLT::scalar(64)) &&
8735f757f3fSDimitry Andric          "8=>64 Zext is handled by tablegen");
8745f757f3fSDimitry Andric   assert(!(SrcTy == LLT::scalar(16) && DstTy == LLT::scalar(64)) &&
8755f757f3fSDimitry Andric          "16=>64 Zext is handled by tablegen");
8765f757f3fSDimitry Andric   assert(!(SrcTy == LLT::scalar(32) && DstTy == LLT::scalar(64)) &&
8775f757f3fSDimitry Andric          "32=>64 Zext is handled by tablegen");
8785f757f3fSDimitry Andric 
8795f757f3fSDimitry Andric   if (SrcTy != LLT::scalar(1))
8805f757f3fSDimitry Andric     return false;
8815f757f3fSDimitry Andric 
8825f757f3fSDimitry Andric   unsigned AndOpc;
8835f757f3fSDimitry Andric   if (DstTy == LLT::scalar(8))
8845f757f3fSDimitry Andric     AndOpc = X86::AND8ri;
8855f757f3fSDimitry Andric   else if (DstTy == LLT::scalar(16))
8865f757f3fSDimitry Andric     AndOpc = X86::AND16ri;
8875f757f3fSDimitry Andric   else if (DstTy == LLT::scalar(32))
8885f757f3fSDimitry Andric     AndOpc = X86::AND32ri;
8895f757f3fSDimitry Andric   else if (DstTy == LLT::scalar(64))
8905f757f3fSDimitry Andric     AndOpc = X86::AND64ri32;
8915f757f3fSDimitry Andric   else
8925f757f3fSDimitry Andric     return false;
8935f757f3fSDimitry Andric 
8945f757f3fSDimitry Andric   Register DefReg = SrcReg;
8955f757f3fSDimitry Andric   if (DstTy != LLT::scalar(8)) {
8965f757f3fSDimitry Andric     Register ImpDefReg =
8975f757f3fSDimitry Andric         MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
8985f757f3fSDimitry Andric     BuildMI(*I.getParent(), I, I.getDebugLoc(),
8995f757f3fSDimitry Andric             TII.get(TargetOpcode::IMPLICIT_DEF), ImpDefReg);
9005f757f3fSDimitry Andric 
9015f757f3fSDimitry Andric     DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
9025f757f3fSDimitry Andric     BuildMI(*I.getParent(), I, I.getDebugLoc(),
9035f757f3fSDimitry Andric             TII.get(TargetOpcode::INSERT_SUBREG), DefReg)
9045f757f3fSDimitry Andric         .addReg(ImpDefReg)
9055f757f3fSDimitry Andric         .addReg(SrcReg)
9065f757f3fSDimitry Andric         .addImm(X86::sub_8bit);
9075f757f3fSDimitry Andric   }
9085f757f3fSDimitry Andric 
9095f757f3fSDimitry Andric   MachineInstr &AndInst =
9105f757f3fSDimitry Andric       *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
9115f757f3fSDimitry Andric            .addReg(DefReg)
9125f757f3fSDimitry Andric            .addImm(1);
9135f757f3fSDimitry Andric 
9145f757f3fSDimitry Andric   constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
9155f757f3fSDimitry Andric 
9165f757f3fSDimitry Andric   I.eraseFromParent();
9175f757f3fSDimitry Andric   return true;
9185f757f3fSDimitry Andric }
9195f757f3fSDimitry Andric 
9205f757f3fSDimitry Andric bool X86InstructionSelector::selectAnyext(MachineInstr &I,
9215f757f3fSDimitry Andric                                           MachineRegisterInfo &MRI,
9225f757f3fSDimitry Andric                                           MachineFunction &MF) const {
9235f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction");
9245f757f3fSDimitry Andric 
9255f757f3fSDimitry Andric   const Register DstReg = I.getOperand(0).getReg();
9265f757f3fSDimitry Andric   const Register SrcReg = I.getOperand(1).getReg();
9275f757f3fSDimitry Andric 
9285f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
9295f757f3fSDimitry Andric   const LLT SrcTy = MRI.getType(SrcReg);
9305f757f3fSDimitry Andric 
9315f757f3fSDimitry Andric   const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
9325f757f3fSDimitry Andric   const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
9335f757f3fSDimitry Andric 
9345f757f3fSDimitry Andric   assert(DstRB.getID() == SrcRB.getID() &&
9355f757f3fSDimitry Andric          "G_ANYEXT input/output on different banks\n");
9365f757f3fSDimitry Andric 
9375f757f3fSDimitry Andric   assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
9385f757f3fSDimitry Andric          "G_ANYEXT incorrect operand size");
9395f757f3fSDimitry Andric 
9405f757f3fSDimitry Andric   const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
9415f757f3fSDimitry Andric   const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
9425f757f3fSDimitry Andric 
9435f757f3fSDimitry Andric   // If that's ANY_EXT of the value that lives on the floating class and goes
9445f757f3fSDimitry Andric   // into the vector class, just replace it with copy, as we are able to select
9455f757f3fSDimitry Andric   // it as a regular move.
9465f757f3fSDimitry Andric   if (canTurnIntoCOPY(SrcRC, DstRC))
9475f757f3fSDimitry Andric     return selectTurnIntoCOPY(I, MRI, SrcReg, SrcRC, DstReg, DstRC);
9485f757f3fSDimitry Andric 
9495f757f3fSDimitry Andric   if (DstRB.getID() != X86::GPRRegBankID)
9505f757f3fSDimitry Andric     return false;
9515f757f3fSDimitry Andric 
9525f757f3fSDimitry Andric   if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
9535f757f3fSDimitry Andric       !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
9545f757f3fSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
9555f757f3fSDimitry Andric                       << " operand\n");
9565f757f3fSDimitry Andric     return false;
9575f757f3fSDimitry Andric   }
9585f757f3fSDimitry Andric 
9595f757f3fSDimitry Andric   if (SrcRC == DstRC) {
9605f757f3fSDimitry Andric     I.setDesc(TII.get(X86::COPY));
9615f757f3fSDimitry Andric     return true;
9625f757f3fSDimitry Andric   }
9635f757f3fSDimitry Andric 
9645f757f3fSDimitry Andric   BuildMI(*I.getParent(), I, I.getDebugLoc(),
9655f757f3fSDimitry Andric           TII.get(TargetOpcode::SUBREG_TO_REG))
9665f757f3fSDimitry Andric       .addDef(DstReg)
9675f757f3fSDimitry Andric       .addImm(0)
9685f757f3fSDimitry Andric       .addReg(SrcReg)
9695f757f3fSDimitry Andric       .addImm(getSubRegIndex(SrcRC));
9705f757f3fSDimitry Andric 
9715f757f3fSDimitry Andric   I.eraseFromParent();
9725f757f3fSDimitry Andric   return true;
9735f757f3fSDimitry Andric }
9745f757f3fSDimitry Andric 
9755f757f3fSDimitry Andric bool X86InstructionSelector::selectCmp(MachineInstr &I,
9765f757f3fSDimitry Andric                                        MachineRegisterInfo &MRI,
9775f757f3fSDimitry Andric                                        MachineFunction &MF) const {
9785f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction");
9795f757f3fSDimitry Andric 
9805f757f3fSDimitry Andric   X86::CondCode CC;
9815f757f3fSDimitry Andric   bool SwapArgs;
9825f757f3fSDimitry Andric   std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
9835f757f3fSDimitry Andric       (CmpInst::Predicate)I.getOperand(1).getPredicate());
9845f757f3fSDimitry Andric 
9855f757f3fSDimitry Andric   Register LHS = I.getOperand(2).getReg();
9865f757f3fSDimitry Andric   Register RHS = I.getOperand(3).getReg();
9875f757f3fSDimitry Andric 
9885f757f3fSDimitry Andric   if (SwapArgs)
9895f757f3fSDimitry Andric     std::swap(LHS, RHS);
9905f757f3fSDimitry Andric 
9915f757f3fSDimitry Andric   unsigned OpCmp;
9925f757f3fSDimitry Andric   LLT Ty = MRI.getType(LHS);
9935f757f3fSDimitry Andric 
9945f757f3fSDimitry Andric   switch (Ty.getSizeInBits()) {
9955f757f3fSDimitry Andric   default:
9965f757f3fSDimitry Andric     return false;
9975f757f3fSDimitry Andric   case 8:
9985f757f3fSDimitry Andric     OpCmp = X86::CMP8rr;
9995f757f3fSDimitry Andric     break;
10005f757f3fSDimitry Andric   case 16:
10015f757f3fSDimitry Andric     OpCmp = X86::CMP16rr;
10025f757f3fSDimitry Andric     break;
10035f757f3fSDimitry Andric   case 32:
10045f757f3fSDimitry Andric     OpCmp = X86::CMP32rr;
10055f757f3fSDimitry Andric     break;
10065f757f3fSDimitry Andric   case 64:
10075f757f3fSDimitry Andric     OpCmp = X86::CMP64rr;
10085f757f3fSDimitry Andric     break;
10095f757f3fSDimitry Andric   }
10105f757f3fSDimitry Andric 
10115f757f3fSDimitry Andric   MachineInstr &CmpInst =
10125f757f3fSDimitry Andric       *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
10135f757f3fSDimitry Andric            .addReg(LHS)
10145f757f3fSDimitry Andric            .addReg(RHS);
10155f757f3fSDimitry Andric 
10165f757f3fSDimitry Andric   MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
10175f757f3fSDimitry Andric                                    TII.get(X86::SETCCr), I.getOperand(0).getReg()).addImm(CC);
10185f757f3fSDimitry Andric 
10195f757f3fSDimitry Andric   constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
10205f757f3fSDimitry Andric   constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
10215f757f3fSDimitry Andric 
10225f757f3fSDimitry Andric   I.eraseFromParent();
10235f757f3fSDimitry Andric   return true;
10245f757f3fSDimitry Andric }
10255f757f3fSDimitry Andric 
10265f757f3fSDimitry Andric bool X86InstructionSelector::selectFCmp(MachineInstr &I,
10275f757f3fSDimitry Andric                                         MachineRegisterInfo &MRI,
10285f757f3fSDimitry Andric                                         MachineFunction &MF) const {
10295f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_FCMP) && "unexpected instruction");
10305f757f3fSDimitry Andric 
10315f757f3fSDimitry Andric   Register LhsReg = I.getOperand(2).getReg();
10325f757f3fSDimitry Andric   Register RhsReg = I.getOperand(3).getReg();
10335f757f3fSDimitry Andric   CmpInst::Predicate Predicate =
10345f757f3fSDimitry Andric       (CmpInst::Predicate)I.getOperand(1).getPredicate();
10355f757f3fSDimitry Andric 
10365f757f3fSDimitry Andric   // FCMP_OEQ and FCMP_UNE cannot be checked with a single instruction.
10375f757f3fSDimitry Andric   static const uint16_t SETFOpcTable[2][3] = {
10385f757f3fSDimitry Andric       {X86::COND_E, X86::COND_NP, X86::AND8rr},
10395f757f3fSDimitry Andric       {X86::COND_NE, X86::COND_P, X86::OR8rr}};
10405f757f3fSDimitry Andric   const uint16_t *SETFOpc = nullptr;
10415f757f3fSDimitry Andric   switch (Predicate) {
10425f757f3fSDimitry Andric   default:
10435f757f3fSDimitry Andric     break;
10445f757f3fSDimitry Andric   case CmpInst::FCMP_OEQ:
10455f757f3fSDimitry Andric     SETFOpc = &SETFOpcTable[0][0];
10465f757f3fSDimitry Andric     break;
10475f757f3fSDimitry Andric   case CmpInst::FCMP_UNE:
10485f757f3fSDimitry Andric     SETFOpc = &SETFOpcTable[1][0];
10495f757f3fSDimitry Andric     break;
10505f757f3fSDimitry Andric   }
10515f757f3fSDimitry Andric 
10525f757f3fSDimitry Andric   // Compute the opcode for the CMP instruction.
10535f757f3fSDimitry Andric   unsigned OpCmp;
10545f757f3fSDimitry Andric   LLT Ty = MRI.getType(LhsReg);
10555f757f3fSDimitry Andric   switch (Ty.getSizeInBits()) {
10565f757f3fSDimitry Andric   default:
10575f757f3fSDimitry Andric     return false;
10585f757f3fSDimitry Andric   case 32:
10595f757f3fSDimitry Andric     OpCmp = X86::UCOMISSrr;
10605f757f3fSDimitry Andric     break;
10615f757f3fSDimitry Andric   case 64:
10625f757f3fSDimitry Andric     OpCmp = X86::UCOMISDrr;
10635f757f3fSDimitry Andric     break;
10645f757f3fSDimitry Andric   }
10655f757f3fSDimitry Andric 
10665f757f3fSDimitry Andric   Register ResultReg = I.getOperand(0).getReg();
10675f757f3fSDimitry Andric   RBI.constrainGenericRegister(
10685f757f3fSDimitry Andric       ResultReg,
10695f757f3fSDimitry Andric       *getRegClass(LLT::scalar(8), *RBI.getRegBank(ResultReg, MRI, TRI)), MRI);
10705f757f3fSDimitry Andric   if (SETFOpc) {
10715f757f3fSDimitry Andric     MachineInstr &CmpInst =
10725f757f3fSDimitry Andric         *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
10735f757f3fSDimitry Andric              .addReg(LhsReg)
10745f757f3fSDimitry Andric              .addReg(RhsReg);
10755f757f3fSDimitry Andric 
10765f757f3fSDimitry Andric     Register FlagReg1 = MRI.createVirtualRegister(&X86::GR8RegClass);
10775f757f3fSDimitry Andric     Register FlagReg2 = MRI.createVirtualRegister(&X86::GR8RegClass);
10785f757f3fSDimitry Andric     MachineInstr &Set1 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
10795f757f3fSDimitry Andric                                   TII.get(X86::SETCCr), FlagReg1).addImm(SETFOpc[0]);
10805f757f3fSDimitry Andric     MachineInstr &Set2 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
10815f757f3fSDimitry Andric                                   TII.get(X86::SETCCr), FlagReg2).addImm(SETFOpc[1]);
10825f757f3fSDimitry Andric     MachineInstr &Set3 = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
10835f757f3fSDimitry Andric                                   TII.get(SETFOpc[2]), ResultReg)
10845f757f3fSDimitry Andric                               .addReg(FlagReg1)
10855f757f3fSDimitry Andric                               .addReg(FlagReg2);
10865f757f3fSDimitry Andric     constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
10875f757f3fSDimitry Andric     constrainSelectedInstRegOperands(Set1, TII, TRI, RBI);
10885f757f3fSDimitry Andric     constrainSelectedInstRegOperands(Set2, TII, TRI, RBI);
10895f757f3fSDimitry Andric     constrainSelectedInstRegOperands(Set3, TII, TRI, RBI);
10905f757f3fSDimitry Andric 
10915f757f3fSDimitry Andric     I.eraseFromParent();
10925f757f3fSDimitry Andric     return true;
10935f757f3fSDimitry Andric   }
10945f757f3fSDimitry Andric 
10955f757f3fSDimitry Andric   X86::CondCode CC;
10965f757f3fSDimitry Andric   bool SwapArgs;
10975f757f3fSDimitry Andric   std::tie(CC, SwapArgs) = X86::getX86ConditionCode(Predicate);
10985f757f3fSDimitry Andric   assert(CC <= X86::LAST_VALID_COND && "Unexpected condition code.");
10995f757f3fSDimitry Andric 
11005f757f3fSDimitry Andric   if (SwapArgs)
11015f757f3fSDimitry Andric     std::swap(LhsReg, RhsReg);
11025f757f3fSDimitry Andric 
11035f757f3fSDimitry Andric   // Emit a compare of LHS/RHS.
11045f757f3fSDimitry Andric   MachineInstr &CmpInst =
11055f757f3fSDimitry Andric       *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
11065f757f3fSDimitry Andric            .addReg(LhsReg)
11075f757f3fSDimitry Andric            .addReg(RhsReg);
11085f757f3fSDimitry Andric 
11095f757f3fSDimitry Andric   MachineInstr &Set =
11105f757f3fSDimitry Andric       *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::SETCCr), ResultReg).addImm(CC);
11115f757f3fSDimitry Andric   constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
11125f757f3fSDimitry Andric   constrainSelectedInstRegOperands(Set, TII, TRI, RBI);
11135f757f3fSDimitry Andric   I.eraseFromParent();
11145f757f3fSDimitry Andric   return true;
11155f757f3fSDimitry Andric }
11165f757f3fSDimitry Andric 
11175f757f3fSDimitry Andric bool X86InstructionSelector::selectUAddSub(MachineInstr &I,
11185f757f3fSDimitry Andric                                            MachineRegisterInfo &MRI,
11195f757f3fSDimitry Andric                                            MachineFunction &MF) const {
11205f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_UADDE ||
11215f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_UADDO ||
11225f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_USUBE ||
11235f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_USUBO) &&
11245f757f3fSDimitry Andric          "unexpected instruction");
11255f757f3fSDimitry Andric 
11265f757f3fSDimitry Andric   const Register DstReg = I.getOperand(0).getReg();
11275f757f3fSDimitry Andric   const Register CarryOutReg = I.getOperand(1).getReg();
11285f757f3fSDimitry Andric   const Register Op0Reg = I.getOperand(2).getReg();
11295f757f3fSDimitry Andric   const Register Op1Reg = I.getOperand(3).getReg();
11305f757f3fSDimitry Andric   bool IsSub = I.getOpcode() == TargetOpcode::G_USUBE ||
11315f757f3fSDimitry Andric                I.getOpcode() == TargetOpcode::G_USUBO;
11325f757f3fSDimitry Andric   bool HasCarryIn = I.getOpcode() == TargetOpcode::G_UADDE ||
11335f757f3fSDimitry Andric                     I.getOpcode() == TargetOpcode::G_USUBE;
11345f757f3fSDimitry Andric 
11355f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
11365f757f3fSDimitry Andric   assert(DstTy.isScalar() && "selectUAddSub only supported for scalar types");
11375f757f3fSDimitry Andric 
11385f757f3fSDimitry Andric   // TODO: Handle immediate argument variants?
11395f757f3fSDimitry Andric   unsigned OpADC, OpADD, OpSBB, OpSUB;
11405f757f3fSDimitry Andric   switch (DstTy.getSizeInBits()) {
11415f757f3fSDimitry Andric   case 8:
11425f757f3fSDimitry Andric     OpADC = X86::ADC8rr;
11435f757f3fSDimitry Andric     OpADD = X86::ADD8rr;
11445f757f3fSDimitry Andric     OpSBB = X86::SBB8rr;
11455f757f3fSDimitry Andric     OpSUB = X86::SUB8rr;
11465f757f3fSDimitry Andric     break;
11475f757f3fSDimitry Andric   case 16:
11485f757f3fSDimitry Andric     OpADC = X86::ADC16rr;
11495f757f3fSDimitry Andric     OpADD = X86::ADD16rr;
11505f757f3fSDimitry Andric     OpSBB = X86::SBB16rr;
11515f757f3fSDimitry Andric     OpSUB = X86::SUB16rr;
11525f757f3fSDimitry Andric     break;
11535f757f3fSDimitry Andric   case 32:
11545f757f3fSDimitry Andric     OpADC = X86::ADC32rr;
11555f757f3fSDimitry Andric     OpADD = X86::ADD32rr;
11565f757f3fSDimitry Andric     OpSBB = X86::SBB32rr;
11575f757f3fSDimitry Andric     OpSUB = X86::SUB32rr;
11585f757f3fSDimitry Andric     break;
11595f757f3fSDimitry Andric   case 64:
11605f757f3fSDimitry Andric     OpADC = X86::ADC64rr;
11615f757f3fSDimitry Andric     OpADD = X86::ADD64rr;
11625f757f3fSDimitry Andric     OpSBB = X86::SBB64rr;
11635f757f3fSDimitry Andric     OpSUB = X86::SUB64rr;
11645f757f3fSDimitry Andric     break;
11655f757f3fSDimitry Andric   default:
11665f757f3fSDimitry Andric     llvm_unreachable("selectUAddSub unsupported type.");
11675f757f3fSDimitry Andric   }
11685f757f3fSDimitry Andric 
11695f757f3fSDimitry Andric   const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
11705f757f3fSDimitry Andric   const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
11715f757f3fSDimitry Andric 
11725f757f3fSDimitry Andric   unsigned Opcode = IsSub ? OpSUB : OpADD;
11735f757f3fSDimitry Andric 
11745f757f3fSDimitry Andric   // G_UADDE/G_USUBE - find CarryIn def instruction.
11755f757f3fSDimitry Andric   if (HasCarryIn) {
11765f757f3fSDimitry Andric     Register CarryInReg = I.getOperand(4).getReg();
11775f757f3fSDimitry Andric     MachineInstr *Def = MRI.getVRegDef(CarryInReg);
11785f757f3fSDimitry Andric     while (Def->getOpcode() == TargetOpcode::G_TRUNC) {
11795f757f3fSDimitry Andric       CarryInReg = Def->getOperand(1).getReg();
11805f757f3fSDimitry Andric       Def = MRI.getVRegDef(CarryInReg);
11815f757f3fSDimitry Andric     }
11825f757f3fSDimitry Andric 
11835f757f3fSDimitry Andric     // TODO - handle more CF generating instructions
11845f757f3fSDimitry Andric     if (Def->getOpcode() == TargetOpcode::G_UADDE ||
11855f757f3fSDimitry Andric         Def->getOpcode() == TargetOpcode::G_UADDO ||
11865f757f3fSDimitry Andric         Def->getOpcode() == TargetOpcode::G_USUBE ||
11875f757f3fSDimitry Andric         Def->getOpcode() == TargetOpcode::G_USUBO) {
11885f757f3fSDimitry Andric       // carry set by prev ADD/SUB.
11895f757f3fSDimitry Andric       BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY),
11905f757f3fSDimitry Andric               X86::EFLAGS)
11915f757f3fSDimitry Andric           .addReg(CarryInReg);
11925f757f3fSDimitry Andric 
11935f757f3fSDimitry Andric       if (!RBI.constrainGenericRegister(CarryInReg, *DstRC, MRI))
11945f757f3fSDimitry Andric         return false;
11955f757f3fSDimitry Andric 
11965f757f3fSDimitry Andric       Opcode = IsSub ? OpSBB : OpADC;
11975f757f3fSDimitry Andric     } else if (auto val = getIConstantVRegVal(CarryInReg, MRI)) {
11985f757f3fSDimitry Andric       // carry is constant, support only 0.
11995f757f3fSDimitry Andric       if (*val != 0)
12005f757f3fSDimitry Andric         return false;
12015f757f3fSDimitry Andric 
12025f757f3fSDimitry Andric       Opcode = IsSub ? OpSUB : OpADD;
12035f757f3fSDimitry Andric     } else
12045f757f3fSDimitry Andric       return false;
12055f757f3fSDimitry Andric   }
12065f757f3fSDimitry Andric 
12075f757f3fSDimitry Andric   MachineInstr &Inst =
12085f757f3fSDimitry Andric       *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
12095f757f3fSDimitry Andric            .addReg(Op0Reg)
12105f757f3fSDimitry Andric            .addReg(Op1Reg);
12115f757f3fSDimitry Andric 
12125f757f3fSDimitry Andric   BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
12135f757f3fSDimitry Andric       .addReg(X86::EFLAGS);
12145f757f3fSDimitry Andric 
12155f757f3fSDimitry Andric   if (!constrainSelectedInstRegOperands(Inst, TII, TRI, RBI) ||
12165f757f3fSDimitry Andric       !RBI.constrainGenericRegister(CarryOutReg, *DstRC, MRI))
12175f757f3fSDimitry Andric     return false;
12185f757f3fSDimitry Andric 
12195f757f3fSDimitry Andric   I.eraseFromParent();
12205f757f3fSDimitry Andric   return true;
12215f757f3fSDimitry Andric }
12225f757f3fSDimitry Andric 
12235f757f3fSDimitry Andric bool X86InstructionSelector::selectExtract(MachineInstr &I,
12245f757f3fSDimitry Andric                                            MachineRegisterInfo &MRI,
12255f757f3fSDimitry Andric                                            MachineFunction &MF) const {
12265f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_EXTRACT) &&
12275f757f3fSDimitry Andric          "unexpected instruction");
12285f757f3fSDimitry Andric 
12295f757f3fSDimitry Andric   const Register DstReg = I.getOperand(0).getReg();
12305f757f3fSDimitry Andric   const Register SrcReg = I.getOperand(1).getReg();
12315f757f3fSDimitry Andric   int64_t Index = I.getOperand(2).getImm();
12325f757f3fSDimitry Andric 
12335f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
12345f757f3fSDimitry Andric   const LLT SrcTy = MRI.getType(SrcReg);
12355f757f3fSDimitry Andric 
12365f757f3fSDimitry Andric   // Meanwile handle vector type only.
12375f757f3fSDimitry Andric   if (!DstTy.isVector())
12385f757f3fSDimitry Andric     return false;
12395f757f3fSDimitry Andric 
12405f757f3fSDimitry Andric   if (Index % DstTy.getSizeInBits() != 0)
12415f757f3fSDimitry Andric     return false; // Not extract subvector.
12425f757f3fSDimitry Andric 
12435f757f3fSDimitry Andric   if (Index == 0) {
12445f757f3fSDimitry Andric     // Replace by extract subreg copy.
12455f757f3fSDimitry Andric     if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF))
12465f757f3fSDimitry Andric       return false;
12475f757f3fSDimitry Andric 
12485f757f3fSDimitry Andric     I.eraseFromParent();
12495f757f3fSDimitry Andric     return true;
12505f757f3fSDimitry Andric   }
12515f757f3fSDimitry Andric 
12525f757f3fSDimitry Andric   bool HasAVX = STI.hasAVX();
12535f757f3fSDimitry Andric   bool HasAVX512 = STI.hasAVX512();
12545f757f3fSDimitry Andric   bool HasVLX = STI.hasVLX();
12555f757f3fSDimitry Andric 
12565f757f3fSDimitry Andric   if (SrcTy.getSizeInBits() == 256 && DstTy.getSizeInBits() == 128) {
12575f757f3fSDimitry Andric     if (HasVLX)
12585f757f3fSDimitry Andric       I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr));
12595f757f3fSDimitry Andric     else if (HasAVX)
12605f757f3fSDimitry Andric       I.setDesc(TII.get(X86::VEXTRACTF128rr));
12615f757f3fSDimitry Andric     else
12625f757f3fSDimitry Andric       return false;
12635f757f3fSDimitry Andric   } else if (SrcTy.getSizeInBits() == 512 && HasAVX512) {
12645f757f3fSDimitry Andric     if (DstTy.getSizeInBits() == 128)
12655f757f3fSDimitry Andric       I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr));
12665f757f3fSDimitry Andric     else if (DstTy.getSizeInBits() == 256)
12675f757f3fSDimitry Andric       I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr));
12685f757f3fSDimitry Andric     else
12695f757f3fSDimitry Andric       return false;
12705f757f3fSDimitry Andric   } else
12715f757f3fSDimitry Andric     return false;
12725f757f3fSDimitry Andric 
12735f757f3fSDimitry Andric   // Convert to X86 VEXTRACT immediate.
12745f757f3fSDimitry Andric   Index = Index / DstTy.getSizeInBits();
12755f757f3fSDimitry Andric   I.getOperand(2).setImm(Index);
12765f757f3fSDimitry Andric 
12775f757f3fSDimitry Andric   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
12785f757f3fSDimitry Andric }
12795f757f3fSDimitry Andric 
12805f757f3fSDimitry Andric bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg,
12815f757f3fSDimitry Andric                                                MachineInstr &I,
12825f757f3fSDimitry Andric                                                MachineRegisterInfo &MRI,
12835f757f3fSDimitry Andric                                                MachineFunction &MF) const {
12845f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
12855f757f3fSDimitry Andric   const LLT SrcTy = MRI.getType(SrcReg);
12865f757f3fSDimitry Andric   unsigned SubIdx = X86::NoSubRegister;
12875f757f3fSDimitry Andric 
12885f757f3fSDimitry Andric   if (!DstTy.isVector() || !SrcTy.isVector())
12895f757f3fSDimitry Andric     return false;
12905f757f3fSDimitry Andric 
12915f757f3fSDimitry Andric   assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() &&
12925f757f3fSDimitry Andric          "Incorrect Src/Dst register size");
12935f757f3fSDimitry Andric 
12945f757f3fSDimitry Andric   if (DstTy.getSizeInBits() == 128)
12955f757f3fSDimitry Andric     SubIdx = X86::sub_xmm;
12965f757f3fSDimitry Andric   else if (DstTy.getSizeInBits() == 256)
12975f757f3fSDimitry Andric     SubIdx = X86::sub_ymm;
12985f757f3fSDimitry Andric   else
12995f757f3fSDimitry Andric     return false;
13005f757f3fSDimitry Andric 
13015f757f3fSDimitry Andric   const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
13025f757f3fSDimitry Andric   const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
13035f757f3fSDimitry Andric 
13045f757f3fSDimitry Andric   SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
13055f757f3fSDimitry Andric 
13065f757f3fSDimitry Andric   if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
13075f757f3fSDimitry Andric       !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
13085f757f3fSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to constrain EXTRACT_SUBREG\n");
13095f757f3fSDimitry Andric     return false;
13105f757f3fSDimitry Andric   }
13115f757f3fSDimitry Andric 
13125f757f3fSDimitry Andric   BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg)
13135f757f3fSDimitry Andric       .addReg(SrcReg, 0, SubIdx);
13145f757f3fSDimitry Andric 
13155f757f3fSDimitry Andric   return true;
13165f757f3fSDimitry Andric }
13175f757f3fSDimitry Andric 
13185f757f3fSDimitry Andric bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg,
13195f757f3fSDimitry Andric                                               MachineInstr &I,
13205f757f3fSDimitry Andric                                               MachineRegisterInfo &MRI,
13215f757f3fSDimitry Andric                                               MachineFunction &MF) const {
13225f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
13235f757f3fSDimitry Andric   const LLT SrcTy = MRI.getType(SrcReg);
13245f757f3fSDimitry Andric   unsigned SubIdx = X86::NoSubRegister;
13255f757f3fSDimitry Andric 
13265f757f3fSDimitry Andric   // TODO: support scalar types
13275f757f3fSDimitry Andric   if (!DstTy.isVector() || !SrcTy.isVector())
13285f757f3fSDimitry Andric     return false;
13295f757f3fSDimitry Andric 
13305f757f3fSDimitry Andric   assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() &&
13315f757f3fSDimitry Andric          "Incorrect Src/Dst register size");
13325f757f3fSDimitry Andric 
13335f757f3fSDimitry Andric   if (SrcTy.getSizeInBits() == 128)
13345f757f3fSDimitry Andric     SubIdx = X86::sub_xmm;
13355f757f3fSDimitry Andric   else if (SrcTy.getSizeInBits() == 256)
13365f757f3fSDimitry Andric     SubIdx = X86::sub_ymm;
13375f757f3fSDimitry Andric   else
13385f757f3fSDimitry Andric     return false;
13395f757f3fSDimitry Andric 
13405f757f3fSDimitry Andric   const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
13415f757f3fSDimitry Andric   const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
13425f757f3fSDimitry Andric 
13435f757f3fSDimitry Andric   if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
13445f757f3fSDimitry Andric       !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
13455f757f3fSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n");
13465f757f3fSDimitry Andric     return false;
13475f757f3fSDimitry Andric   }
13485f757f3fSDimitry Andric 
13495f757f3fSDimitry Andric   BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY))
13505f757f3fSDimitry Andric       .addReg(DstReg, RegState::DefineNoRead, SubIdx)
13515f757f3fSDimitry Andric       .addReg(SrcReg);
13525f757f3fSDimitry Andric 
13535f757f3fSDimitry Andric   return true;
13545f757f3fSDimitry Andric }
13555f757f3fSDimitry Andric 
13565f757f3fSDimitry Andric bool X86InstructionSelector::selectInsert(MachineInstr &I,
13575f757f3fSDimitry Andric                                           MachineRegisterInfo &MRI,
13585f757f3fSDimitry Andric                                           MachineFunction &MF) const {
13595f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction");
13605f757f3fSDimitry Andric 
13615f757f3fSDimitry Andric   const Register DstReg = I.getOperand(0).getReg();
13625f757f3fSDimitry Andric   const Register SrcReg = I.getOperand(1).getReg();
13635f757f3fSDimitry Andric   const Register InsertReg = I.getOperand(2).getReg();
13645f757f3fSDimitry Andric   int64_t Index = I.getOperand(3).getImm();
13655f757f3fSDimitry Andric 
13665f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
13675f757f3fSDimitry Andric   const LLT InsertRegTy = MRI.getType(InsertReg);
13685f757f3fSDimitry Andric 
13695f757f3fSDimitry Andric   // Meanwile handle vector type only.
13705f757f3fSDimitry Andric   if (!DstTy.isVector())
13715f757f3fSDimitry Andric     return false;
13725f757f3fSDimitry Andric 
13735f757f3fSDimitry Andric   if (Index % InsertRegTy.getSizeInBits() != 0)
13745f757f3fSDimitry Andric     return false; // Not insert subvector.
13755f757f3fSDimitry Andric 
13765f757f3fSDimitry Andric   if (Index == 0 && MRI.getVRegDef(SrcReg)->isImplicitDef()) {
13775f757f3fSDimitry Andric     // Replace by subreg copy.
13785f757f3fSDimitry Andric     if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF))
13795f757f3fSDimitry Andric       return false;
13805f757f3fSDimitry Andric 
13815f757f3fSDimitry Andric     I.eraseFromParent();
13825f757f3fSDimitry Andric     return true;
13835f757f3fSDimitry Andric   }
13845f757f3fSDimitry Andric 
13855f757f3fSDimitry Andric   bool HasAVX = STI.hasAVX();
13865f757f3fSDimitry Andric   bool HasAVX512 = STI.hasAVX512();
13875f757f3fSDimitry Andric   bool HasVLX = STI.hasVLX();
13885f757f3fSDimitry Andric 
13895f757f3fSDimitry Andric   if (DstTy.getSizeInBits() == 256 && InsertRegTy.getSizeInBits() == 128) {
13905f757f3fSDimitry Andric     if (HasVLX)
13915f757f3fSDimitry Andric       I.setDesc(TII.get(X86::VINSERTF32x4Z256rr));
13925f757f3fSDimitry Andric     else if (HasAVX)
13935f757f3fSDimitry Andric       I.setDesc(TII.get(X86::VINSERTF128rr));
13945f757f3fSDimitry Andric     else
13955f757f3fSDimitry Andric       return false;
13965f757f3fSDimitry Andric   } else if (DstTy.getSizeInBits() == 512 && HasAVX512) {
13975f757f3fSDimitry Andric     if (InsertRegTy.getSizeInBits() == 128)
13985f757f3fSDimitry Andric       I.setDesc(TII.get(X86::VINSERTF32x4Zrr));
13995f757f3fSDimitry Andric     else if (InsertRegTy.getSizeInBits() == 256)
14005f757f3fSDimitry Andric       I.setDesc(TII.get(X86::VINSERTF64x4Zrr));
14015f757f3fSDimitry Andric     else
14025f757f3fSDimitry Andric       return false;
14035f757f3fSDimitry Andric   } else
14045f757f3fSDimitry Andric     return false;
14055f757f3fSDimitry Andric 
14065f757f3fSDimitry Andric   // Convert to X86 VINSERT immediate.
14075f757f3fSDimitry Andric   Index = Index / InsertRegTy.getSizeInBits();
14085f757f3fSDimitry Andric 
14095f757f3fSDimitry Andric   I.getOperand(3).setImm(Index);
14105f757f3fSDimitry Andric 
14115f757f3fSDimitry Andric   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
14125f757f3fSDimitry Andric }
14135f757f3fSDimitry Andric 
14145f757f3fSDimitry Andric bool X86InstructionSelector::selectUnmergeValues(
14155f757f3fSDimitry Andric     MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) {
14165f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
14175f757f3fSDimitry Andric          "unexpected instruction");
14185f757f3fSDimitry Andric 
14195f757f3fSDimitry Andric   // Split to extracts.
14205f757f3fSDimitry Andric   unsigned NumDefs = I.getNumOperands() - 1;
14215f757f3fSDimitry Andric   Register SrcReg = I.getOperand(NumDefs).getReg();
14225f757f3fSDimitry Andric   unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
14235f757f3fSDimitry Andric 
14245f757f3fSDimitry Andric   for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
14255f757f3fSDimitry Andric     MachineInstr &ExtrInst =
14265f757f3fSDimitry Andric         *BuildMI(*I.getParent(), I, I.getDebugLoc(),
14275f757f3fSDimitry Andric                  TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg())
14285f757f3fSDimitry Andric              .addReg(SrcReg)
14295f757f3fSDimitry Andric              .addImm(Idx * DefSize);
14305f757f3fSDimitry Andric 
14315f757f3fSDimitry Andric     if (!select(ExtrInst))
14325f757f3fSDimitry Andric       return false;
14335f757f3fSDimitry Andric   }
14345f757f3fSDimitry Andric 
14355f757f3fSDimitry Andric   I.eraseFromParent();
14365f757f3fSDimitry Andric   return true;
14375f757f3fSDimitry Andric }
14385f757f3fSDimitry Andric 
14395f757f3fSDimitry Andric bool X86InstructionSelector::selectMergeValues(
14405f757f3fSDimitry Andric     MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) {
14415f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES ||
14425f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_CONCAT_VECTORS) &&
14435f757f3fSDimitry Andric          "unexpected instruction");
14445f757f3fSDimitry Andric 
14455f757f3fSDimitry Andric   // Split to inserts.
14465f757f3fSDimitry Andric   Register DstReg = I.getOperand(0).getReg();
14475f757f3fSDimitry Andric   Register SrcReg0 = I.getOperand(1).getReg();
14485f757f3fSDimitry Andric 
14495f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
14505f757f3fSDimitry Andric   const LLT SrcTy = MRI.getType(SrcReg0);
14515f757f3fSDimitry Andric   unsigned SrcSize = SrcTy.getSizeInBits();
14525f757f3fSDimitry Andric 
14535f757f3fSDimitry Andric   const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
14545f757f3fSDimitry Andric 
14555f757f3fSDimitry Andric   // For the first src use insertSubReg.
14565f757f3fSDimitry Andric   Register DefReg = MRI.createGenericVirtualRegister(DstTy);
14575f757f3fSDimitry Andric   MRI.setRegBank(DefReg, RegBank);
14585f757f3fSDimitry Andric   if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF))
14595f757f3fSDimitry Andric     return false;
14605f757f3fSDimitry Andric 
14615f757f3fSDimitry Andric   for (unsigned Idx = 2; Idx < I.getNumOperands(); ++Idx) {
14625f757f3fSDimitry Andric     Register Tmp = MRI.createGenericVirtualRegister(DstTy);
14635f757f3fSDimitry Andric     MRI.setRegBank(Tmp, RegBank);
14645f757f3fSDimitry Andric 
14655f757f3fSDimitry Andric     MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
14665f757f3fSDimitry Andric                                         TII.get(TargetOpcode::G_INSERT), Tmp)
14675f757f3fSDimitry Andric                                     .addReg(DefReg)
14685f757f3fSDimitry Andric                                     .addReg(I.getOperand(Idx).getReg())
14695f757f3fSDimitry Andric                                     .addImm((Idx - 1) * SrcSize);
14705f757f3fSDimitry Andric 
14715f757f3fSDimitry Andric     DefReg = Tmp;
14725f757f3fSDimitry Andric 
14735f757f3fSDimitry Andric     if (!select(InsertInst))
14745f757f3fSDimitry Andric       return false;
14755f757f3fSDimitry Andric   }
14765f757f3fSDimitry Andric 
14775f757f3fSDimitry Andric   MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
14785f757f3fSDimitry Andric                                     TII.get(TargetOpcode::COPY), DstReg)
14795f757f3fSDimitry Andric                                 .addReg(DefReg);
14805f757f3fSDimitry Andric 
14815f757f3fSDimitry Andric   if (!select(CopyInst))
14825f757f3fSDimitry Andric     return false;
14835f757f3fSDimitry Andric 
14845f757f3fSDimitry Andric   I.eraseFromParent();
14855f757f3fSDimitry Andric   return true;
14865f757f3fSDimitry Andric }
14875f757f3fSDimitry Andric 
14885f757f3fSDimitry Andric bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
14895f757f3fSDimitry Andric                                               MachineRegisterInfo &MRI,
14905f757f3fSDimitry Andric                                               MachineFunction &MF) const {
14915f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction");
14925f757f3fSDimitry Andric 
14935f757f3fSDimitry Andric   const Register CondReg = I.getOperand(0).getReg();
14945f757f3fSDimitry Andric   MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
14955f757f3fSDimitry Andric 
14965f757f3fSDimitry Andric   MachineInstr &TestInst =
14975f757f3fSDimitry Andric       *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
14985f757f3fSDimitry Andric            .addReg(CondReg)
14995f757f3fSDimitry Andric            .addImm(1);
15005f757f3fSDimitry Andric   BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JCC_1))
15015f757f3fSDimitry Andric       .addMBB(DestMBB).addImm(X86::COND_NE);
15025f757f3fSDimitry Andric 
15035f757f3fSDimitry Andric   constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
15045f757f3fSDimitry Andric 
15055f757f3fSDimitry Andric   I.eraseFromParent();
15065f757f3fSDimitry Andric   return true;
15075f757f3fSDimitry Andric }
15085f757f3fSDimitry Andric 
15095f757f3fSDimitry Andric bool X86InstructionSelector::materializeFP(MachineInstr &I,
15105f757f3fSDimitry Andric                                            MachineRegisterInfo &MRI,
15115f757f3fSDimitry Andric                                            MachineFunction &MF) const {
15125f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
15135f757f3fSDimitry Andric          "unexpected instruction");
15145f757f3fSDimitry Andric 
15155f757f3fSDimitry Andric   // Can't handle alternate code models yet.
15165f757f3fSDimitry Andric   CodeModel::Model CM = TM.getCodeModel();
15175f757f3fSDimitry Andric   if (CM != CodeModel::Small && CM != CodeModel::Large)
15185f757f3fSDimitry Andric     return false;
15195f757f3fSDimitry Andric 
15205f757f3fSDimitry Andric   const Register DstReg = I.getOperand(0).getReg();
15215f757f3fSDimitry Andric   const LLT DstTy = MRI.getType(DstReg);
15225f757f3fSDimitry Andric   const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1523*0fca6ea1SDimitry Andric   // Create the load from the constant pool.
1524*0fca6ea1SDimitry Andric   const ConstantFP *CFP = I.getOperand(1).getFPImm();
1525*0fca6ea1SDimitry Andric   const auto &DL = MF.getDataLayout();
1526*0fca6ea1SDimitry Andric   Align Alignment = DL.getPrefTypeAlign(CFP->getType());
15275f757f3fSDimitry Andric   const DebugLoc &DbgLoc = I.getDebugLoc();
15285f757f3fSDimitry Andric 
15295f757f3fSDimitry Andric   unsigned Opc =
15305f757f3fSDimitry Andric       getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Alignment);
15315f757f3fSDimitry Andric 
15325f757f3fSDimitry Andric   unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Alignment);
15335f757f3fSDimitry Andric   MachineInstr *LoadInst = nullptr;
15345f757f3fSDimitry Andric   unsigned char OpFlag = STI.classifyLocalReference(nullptr);
15355f757f3fSDimitry Andric 
15365f757f3fSDimitry Andric   if (CM == CodeModel::Large && STI.is64Bit()) {
15375f757f3fSDimitry Andric     // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
15385f757f3fSDimitry Andric     // they cannot be folded into immediate fields.
15395f757f3fSDimitry Andric 
15405f757f3fSDimitry Andric     Register AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
15415f757f3fSDimitry Andric     BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
15425f757f3fSDimitry Andric         .addConstantPoolIndex(CPI, 0, OpFlag);
15435f757f3fSDimitry Andric 
15445f757f3fSDimitry Andric     MachineMemOperand *MMO = MF.getMachineMemOperand(
15455f757f3fSDimitry Andric         MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
1546*0fca6ea1SDimitry Andric         LLT::pointer(0, DL.getPointerSizeInBits()), Alignment);
15475f757f3fSDimitry Andric 
15485f757f3fSDimitry Andric     LoadInst =
15495f757f3fSDimitry Andric         addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
15505f757f3fSDimitry Andric                      AddrReg)
15515f757f3fSDimitry Andric             .addMemOperand(MMO);
15525f757f3fSDimitry Andric 
15535f757f3fSDimitry Andric   } else if (CM == CodeModel::Small || !STI.is64Bit()) {
15545f757f3fSDimitry Andric     // Handle the case when globals fit in our immediate field.
15555f757f3fSDimitry Andric     // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
15565f757f3fSDimitry Andric 
15575f757f3fSDimitry Andric     // x86-32 PIC requires a PIC base register for constant pools.
15585f757f3fSDimitry Andric     unsigned PICBase = 0;
15595f757f3fSDimitry Andric     if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) {
15605f757f3fSDimitry Andric       // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
15615f757f3fSDimitry Andric       // In DAGISEL the code that initialize it generated by the CGBR pass.
15625f757f3fSDimitry Andric       return false; // TODO support the mode.
15635f757f3fSDimitry Andric     } else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small)
15645f757f3fSDimitry Andric       PICBase = X86::RIP;
15655f757f3fSDimitry Andric 
15665f757f3fSDimitry Andric     LoadInst = addConstantPoolReference(
15675f757f3fSDimitry Andric         BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
15685f757f3fSDimitry Andric         OpFlag);
15695f757f3fSDimitry Andric   } else
15705f757f3fSDimitry Andric     return false;
15715f757f3fSDimitry Andric 
15725f757f3fSDimitry Andric   constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI);
15735f757f3fSDimitry Andric   I.eraseFromParent();
15745f757f3fSDimitry Andric   return true;
15755f757f3fSDimitry Andric }
15765f757f3fSDimitry Andric 
15775f757f3fSDimitry Andric bool X86InstructionSelector::selectImplicitDefOrPHI(
15785f757f3fSDimitry Andric     MachineInstr &I, MachineRegisterInfo &MRI) const {
15795f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
15805f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_PHI) &&
15815f757f3fSDimitry Andric          "unexpected instruction");
15825f757f3fSDimitry Andric 
15835f757f3fSDimitry Andric   Register DstReg = I.getOperand(0).getReg();
15845f757f3fSDimitry Andric 
15855f757f3fSDimitry Andric   if (!MRI.getRegClassOrNull(DstReg)) {
15865f757f3fSDimitry Andric     const LLT DstTy = MRI.getType(DstReg);
15875f757f3fSDimitry Andric     const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
15885f757f3fSDimitry Andric 
15895f757f3fSDimitry Andric     if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
15905f757f3fSDimitry Andric       LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
15915f757f3fSDimitry Andric                         << " operand\n");
15925f757f3fSDimitry Andric       return false;
15935f757f3fSDimitry Andric     }
15945f757f3fSDimitry Andric   }
15955f757f3fSDimitry Andric 
15965f757f3fSDimitry Andric   if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
15975f757f3fSDimitry Andric     I.setDesc(TII.get(X86::IMPLICIT_DEF));
15985f757f3fSDimitry Andric   else
15995f757f3fSDimitry Andric     I.setDesc(TII.get(X86::PHI));
16005f757f3fSDimitry Andric 
16015f757f3fSDimitry Andric   return true;
16025f757f3fSDimitry Andric }
16035f757f3fSDimitry Andric 
16045f757f3fSDimitry Andric bool X86InstructionSelector::selectMulDivRem(MachineInstr &I,
16055f757f3fSDimitry Andric                                              MachineRegisterInfo &MRI,
16065f757f3fSDimitry Andric                                              MachineFunction &MF) const {
16075f757f3fSDimitry Andric   // The implementation of this function is adapted from X86FastISel.
16085f757f3fSDimitry Andric   assert((I.getOpcode() == TargetOpcode::G_MUL ||
16095f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_SMULH ||
16105f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_UMULH ||
16115f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_SDIV ||
16125f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_SREM ||
16135f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_UDIV ||
16145f757f3fSDimitry Andric           I.getOpcode() == TargetOpcode::G_UREM) &&
16155f757f3fSDimitry Andric          "unexpected instruction");
16165f757f3fSDimitry Andric 
16175f757f3fSDimitry Andric   const Register DstReg = I.getOperand(0).getReg();
16185f757f3fSDimitry Andric   const Register Op1Reg = I.getOperand(1).getReg();
16195f757f3fSDimitry Andric   const Register Op2Reg = I.getOperand(2).getReg();
16205f757f3fSDimitry Andric 
16215f757f3fSDimitry Andric   const LLT RegTy = MRI.getType(DstReg);
16225f757f3fSDimitry Andric   assert(RegTy == MRI.getType(Op1Reg) && RegTy == MRI.getType(Op2Reg) &&
16235f757f3fSDimitry Andric          "Arguments and return value types must match");
16245f757f3fSDimitry Andric 
16255f757f3fSDimitry Andric   const RegisterBank *RegRB = RBI.getRegBank(DstReg, MRI, TRI);
16265f757f3fSDimitry Andric   if (!RegRB || RegRB->getID() != X86::GPRRegBankID)
16275f757f3fSDimitry Andric     return false;
16285f757f3fSDimitry Andric 
16295f757f3fSDimitry Andric   const static unsigned NumTypes = 4; // i8, i16, i32, i64
16305f757f3fSDimitry Andric   const static unsigned NumOps = 7;   // SDiv/SRem/UDiv/URem/Mul/SMulH/UMulh
16315f757f3fSDimitry Andric   const static bool S = true;         // IsSigned
16325f757f3fSDimitry Andric   const static bool U = false;        // !IsSigned
16335f757f3fSDimitry Andric   const static unsigned Copy = TargetOpcode::COPY;
16345f757f3fSDimitry Andric 
16355f757f3fSDimitry Andric   // For the X86 IDIV instruction, in most cases the dividend
16365f757f3fSDimitry Andric   // (numerator) must be in a specific register pair highreg:lowreg,
16375f757f3fSDimitry Andric   // producing the quotient in lowreg and the remainder in highreg.
16385f757f3fSDimitry Andric   // For most data types, to set up the instruction, the dividend is
16395f757f3fSDimitry Andric   // copied into lowreg, and lowreg is sign-extended into highreg.  The
16405f757f3fSDimitry Andric   // exception is i8, where the dividend is defined as a single register rather
16415f757f3fSDimitry Andric   // than a register pair, and we therefore directly sign-extend the dividend
16425f757f3fSDimitry Andric   // into lowreg, instead of copying, and ignore the highreg.
16435f757f3fSDimitry Andric   const static struct MulDivRemEntry {
16445f757f3fSDimitry Andric     // The following portion depends only on the data type.
16455f757f3fSDimitry Andric     unsigned SizeInBits;
16465f757f3fSDimitry Andric     unsigned LowInReg;  // low part of the register pair
16475f757f3fSDimitry Andric     unsigned HighInReg; // high part of the register pair
16485f757f3fSDimitry Andric     // The following portion depends on both the data type and the operation.
16495f757f3fSDimitry Andric     struct MulDivRemResult {
16505f757f3fSDimitry Andric       unsigned OpMulDivRem;     // The specific MUL/DIV opcode to use.
16515f757f3fSDimitry Andric       unsigned OpSignExtend;    // Opcode for sign-extending lowreg into
16525f757f3fSDimitry Andric                                 // highreg, or copying a zero into highreg.
16535f757f3fSDimitry Andric       unsigned OpCopy;          // Opcode for copying dividend into lowreg, or
16545f757f3fSDimitry Andric                                 // zero/sign-extending into lowreg for i8.
16555f757f3fSDimitry Andric       unsigned ResultReg;       // Register containing the desired result.
16565f757f3fSDimitry Andric       bool IsOpSigned;          // Whether to use signed or unsigned form.
16575f757f3fSDimitry Andric     } ResultTable[NumOps];
16585f757f3fSDimitry Andric   } OpTable[NumTypes] = {
16595f757f3fSDimitry Andric       {8,
16605f757f3fSDimitry Andric        X86::AX,
16615f757f3fSDimitry Andric        0,
16625f757f3fSDimitry Andric        {
16635f757f3fSDimitry Andric            {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AL, S}, // SDiv
16645f757f3fSDimitry Andric            {X86::IDIV8r, 0, X86::MOVSX16rr8, X86::AH, S}, // SRem
16655f757f3fSDimitry Andric            {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AL, U},  // UDiv
16665f757f3fSDimitry Andric            {X86::DIV8r, 0, X86::MOVZX16rr8, X86::AH, U},  // URem
16675f757f3fSDimitry Andric            {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AL, S}, // Mul
16685f757f3fSDimitry Andric            {X86::IMUL8r, 0, X86::MOVSX16rr8, X86::AH, S}, // SMulH
16695f757f3fSDimitry Andric            {X86::MUL8r, 0, X86::MOVZX16rr8, X86::AH, U},  // UMulH
16705f757f3fSDimitry Andric        }},                                                // i8
16715f757f3fSDimitry Andric       {16,
16725f757f3fSDimitry Andric        X86::AX,
16735f757f3fSDimitry Andric        X86::DX,
16745f757f3fSDimitry Andric        {
16755f757f3fSDimitry Andric            {X86::IDIV16r, X86::CWD, Copy, X86::AX, S},     // SDiv
16765f757f3fSDimitry Andric            {X86::IDIV16r, X86::CWD, Copy, X86::DX, S},     // SRem
16775f757f3fSDimitry Andric            {X86::DIV16r, X86::MOV32r0, Copy, X86::AX, U},  // UDiv
16785f757f3fSDimitry Andric            {X86::DIV16r, X86::MOV32r0, Copy, X86::DX, U},  // URem
16795f757f3fSDimitry Andric            {X86::IMUL16r, X86::MOV32r0, Copy, X86::AX, S}, // Mul
16805f757f3fSDimitry Andric            {X86::IMUL16r, X86::MOV32r0, Copy, X86::DX, S}, // SMulH
16815f757f3fSDimitry Andric            {X86::MUL16r, X86::MOV32r0, Copy, X86::DX, U},  // UMulH
16825f757f3fSDimitry Andric        }},                                                 // i16
16835f757f3fSDimitry Andric       {32,
16845f757f3fSDimitry Andric        X86::EAX,
16855f757f3fSDimitry Andric        X86::EDX,
16865f757f3fSDimitry Andric        {
16875f757f3fSDimitry Andric            {X86::IDIV32r, X86::CDQ, Copy, X86::EAX, S},     // SDiv
16885f757f3fSDimitry Andric            {X86::IDIV32r, X86::CDQ, Copy, X86::EDX, S},     // SRem
16895f757f3fSDimitry Andric            {X86::DIV32r, X86::MOV32r0, Copy, X86::EAX, U},  // UDiv
16905f757f3fSDimitry Andric            {X86::DIV32r, X86::MOV32r0, Copy, X86::EDX, U},  // URem
16915f757f3fSDimitry Andric            {X86::IMUL32r, X86::MOV32r0, Copy, X86::EAX, S}, // Mul
16925f757f3fSDimitry Andric            {X86::IMUL32r, X86::MOV32r0, Copy, X86::EDX, S}, // SMulH
16935f757f3fSDimitry Andric            {X86::MUL32r, X86::MOV32r0, Copy, X86::EDX, U},  // UMulH
16945f757f3fSDimitry Andric        }},                                                  // i32
16955f757f3fSDimitry Andric       {64,
16965f757f3fSDimitry Andric        X86::RAX,
16975f757f3fSDimitry Andric        X86::RDX,
16985f757f3fSDimitry Andric        {
16995f757f3fSDimitry Andric            {X86::IDIV64r, X86::CQO, Copy, X86::RAX, S},    // SDiv
17005f757f3fSDimitry Andric            {X86::IDIV64r, X86::CQO, Copy, X86::RDX, S},    // SRem
17015f757f3fSDimitry Andric            {X86::DIV64r, X86::MOV32r0, Copy, X86::RAX, U}, // UDiv
17025f757f3fSDimitry Andric            {X86::DIV64r, X86::MOV32r0, Copy, X86::RDX, U}, // URem
17035f757f3fSDimitry Andric            {X86::IMUL64r, X86::MOV32r0, Copy, X86::RAX, S}, // Mul
17045f757f3fSDimitry Andric            {X86::IMUL64r, X86::MOV32r0, Copy, X86::RDX, S}, // SMulH
17055f757f3fSDimitry Andric            {X86::MUL64r, X86::MOV32r0, Copy, X86::RDX, U},  // UMulH
17065f757f3fSDimitry Andric        }},                                                  // i64
17075f757f3fSDimitry Andric   };
17085f757f3fSDimitry Andric 
17095f757f3fSDimitry Andric   auto OpEntryIt = llvm::find_if(OpTable, [RegTy](const MulDivRemEntry &El) {
17105f757f3fSDimitry Andric     return El.SizeInBits == RegTy.getSizeInBits();
17115f757f3fSDimitry Andric   });
17125f757f3fSDimitry Andric   if (OpEntryIt == std::end(OpTable))
17135f757f3fSDimitry Andric     return false;
17145f757f3fSDimitry Andric 
17155f757f3fSDimitry Andric   unsigned OpIndex;
17165f757f3fSDimitry Andric   switch (I.getOpcode()) {
17175f757f3fSDimitry Andric   default:
17185f757f3fSDimitry Andric     llvm_unreachable("Unexpected mul/div/rem opcode");
17195f757f3fSDimitry Andric   case TargetOpcode::G_SDIV:
17205f757f3fSDimitry Andric     OpIndex = 0;
17215f757f3fSDimitry Andric     break;
17225f757f3fSDimitry Andric   case TargetOpcode::G_SREM:
17235f757f3fSDimitry Andric     OpIndex = 1;
17245f757f3fSDimitry Andric     break;
17255f757f3fSDimitry Andric   case TargetOpcode::G_UDIV:
17265f757f3fSDimitry Andric     OpIndex = 2;
17275f757f3fSDimitry Andric     break;
17285f757f3fSDimitry Andric   case TargetOpcode::G_UREM:
17295f757f3fSDimitry Andric     OpIndex = 3;
17305f757f3fSDimitry Andric     break;
17315f757f3fSDimitry Andric   case TargetOpcode::G_MUL:
17325f757f3fSDimitry Andric     OpIndex = 4;
17335f757f3fSDimitry Andric     break;
17345f757f3fSDimitry Andric   case TargetOpcode::G_SMULH:
17355f757f3fSDimitry Andric     OpIndex = 5;
17365f757f3fSDimitry Andric     break;
17375f757f3fSDimitry Andric   case TargetOpcode::G_UMULH:
17385f757f3fSDimitry Andric     OpIndex = 6;
17395f757f3fSDimitry Andric     break;
17405f757f3fSDimitry Andric   }
17415f757f3fSDimitry Andric 
17425f757f3fSDimitry Andric   const MulDivRemEntry &TypeEntry = *OpEntryIt;
17435f757f3fSDimitry Andric   const MulDivRemEntry::MulDivRemResult &OpEntry =
17445f757f3fSDimitry Andric       TypeEntry.ResultTable[OpIndex];
17455f757f3fSDimitry Andric 
17465f757f3fSDimitry Andric   const TargetRegisterClass *RegRC = getRegClass(RegTy, *RegRB);
17475f757f3fSDimitry Andric   if (!RBI.constrainGenericRegister(Op1Reg, *RegRC, MRI) ||
17485f757f3fSDimitry Andric       !RBI.constrainGenericRegister(Op2Reg, *RegRC, MRI) ||
17495f757f3fSDimitry Andric       !RBI.constrainGenericRegister(DstReg, *RegRC, MRI)) {
17505f757f3fSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
17515f757f3fSDimitry Andric                       << " operand\n");
17525f757f3fSDimitry Andric     return false;
17535f757f3fSDimitry Andric   }
17545f757f3fSDimitry Andric 
17555f757f3fSDimitry Andric   // Move op1 into low-order input register.
17565f757f3fSDimitry Andric   BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpEntry.OpCopy),
17575f757f3fSDimitry Andric           TypeEntry.LowInReg)
17585f757f3fSDimitry Andric       .addReg(Op1Reg);
17595f757f3fSDimitry Andric 
17605f757f3fSDimitry Andric   // Zero-extend or sign-extend into high-order input register.
17615f757f3fSDimitry Andric   if (OpEntry.OpSignExtend) {
17625f757f3fSDimitry Andric     if (OpEntry.IsOpSigned)
17635f757f3fSDimitry Andric       BuildMI(*I.getParent(), I, I.getDebugLoc(),
17645f757f3fSDimitry Andric               TII.get(OpEntry.OpSignExtend));
17655f757f3fSDimitry Andric     else {
17665f757f3fSDimitry Andric       Register Zero32 = MRI.createVirtualRegister(&X86::GR32RegClass);
17675f757f3fSDimitry Andric       BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::MOV32r0),
17685f757f3fSDimitry Andric               Zero32);
17695f757f3fSDimitry Andric 
17705f757f3fSDimitry Andric       // Copy the zero into the appropriate sub/super/identical physical
17715f757f3fSDimitry Andric       // register. Unfortunately the operations needed are not uniform enough
17725f757f3fSDimitry Andric       // to fit neatly into the table above.
17735f757f3fSDimitry Andric       if (RegTy.getSizeInBits() == 16) {
17745f757f3fSDimitry Andric         BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy),
17755f757f3fSDimitry Andric                 TypeEntry.HighInReg)
17765f757f3fSDimitry Andric             .addReg(Zero32, 0, X86::sub_16bit);
17775f757f3fSDimitry Andric       } else if (RegTy.getSizeInBits() == 32) {
17785f757f3fSDimitry Andric         BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy),
17795f757f3fSDimitry Andric                 TypeEntry.HighInReg)
17805f757f3fSDimitry Andric             .addReg(Zero32);
17815f757f3fSDimitry Andric       } else if (RegTy.getSizeInBits() == 64) {
17825f757f3fSDimitry Andric         BuildMI(*I.getParent(), I, I.getDebugLoc(),
17835f757f3fSDimitry Andric                 TII.get(TargetOpcode::SUBREG_TO_REG), TypeEntry.HighInReg)
17845f757f3fSDimitry Andric             .addImm(0)
17855f757f3fSDimitry Andric             .addReg(Zero32)
17865f757f3fSDimitry Andric             .addImm(X86::sub_32bit);
17875f757f3fSDimitry Andric       }
17885f757f3fSDimitry Andric     }
17895f757f3fSDimitry Andric   }
17905f757f3fSDimitry Andric 
17915f757f3fSDimitry Andric   // Generate the DIV/IDIV/MUL/IMUL instruction.
17925f757f3fSDimitry Andric   BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpEntry.OpMulDivRem))
17935f757f3fSDimitry Andric       .addReg(Op2Reg);
17945f757f3fSDimitry Andric 
17955f757f3fSDimitry Andric   // For i8 remainder, we can't reference ah directly, as we'll end
17965f757f3fSDimitry Andric   // up with bogus copies like %r9b = COPY %ah. Reference ax
17975f757f3fSDimitry Andric   // instead to prevent ah references in a rex instruction.
17985f757f3fSDimitry Andric   //
17995f757f3fSDimitry Andric   // The current assumption of the fast register allocator is that isel
18005f757f3fSDimitry Andric   // won't generate explicit references to the GR8_NOREX registers. If
18015f757f3fSDimitry Andric   // the allocator and/or the backend get enhanced to be more robust in
18025f757f3fSDimitry Andric   // that regard, this can be, and should be, removed.
18035f757f3fSDimitry Andric   if (OpEntry.ResultReg == X86::AH && STI.is64Bit()) {
18045f757f3fSDimitry Andric     Register SourceSuperReg = MRI.createVirtualRegister(&X86::GR16RegClass);
18055f757f3fSDimitry Andric     Register ResultSuperReg = MRI.createVirtualRegister(&X86::GR16RegClass);
18065f757f3fSDimitry Andric     BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Copy), SourceSuperReg)
18075f757f3fSDimitry Andric         .addReg(X86::AX);
18085f757f3fSDimitry Andric 
18095f757f3fSDimitry Andric     // Shift AX right by 8 bits instead of using AH.
18105f757f3fSDimitry Andric     BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::SHR16ri),
18115f757f3fSDimitry Andric             ResultSuperReg)
18125f757f3fSDimitry Andric         .addReg(SourceSuperReg)
18135f757f3fSDimitry Andric         .addImm(8);
18145f757f3fSDimitry Andric 
18155f757f3fSDimitry Andric     // Now reference the 8-bit subreg of the result.
1816*0fca6ea1SDimitry Andric     BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1817*0fca6ea1SDimitry Andric             DstReg)
1818*0fca6ea1SDimitry Andric         .addReg(ResultSuperReg, 0, X86::sub_8bit);
18195f757f3fSDimitry Andric   } else {
18205f757f3fSDimitry Andric     BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
18215f757f3fSDimitry Andric             DstReg)
18225f757f3fSDimitry Andric         .addReg(OpEntry.ResultReg);
18235f757f3fSDimitry Andric   }
18245f757f3fSDimitry Andric   I.eraseFromParent();
18255f757f3fSDimitry Andric 
18265f757f3fSDimitry Andric   return true;
18275f757f3fSDimitry Andric }
18285f757f3fSDimitry Andric 
18295f757f3fSDimitry Andric bool X86InstructionSelector::selectSelect(MachineInstr &I,
18305f757f3fSDimitry Andric                                           MachineRegisterInfo &MRI,
18315f757f3fSDimitry Andric                                           MachineFunction &MF) const {
18325f757f3fSDimitry Andric   GSelect &Sel = cast<GSelect>(I);
18335f757f3fSDimitry Andric   unsigned DstReg = Sel.getReg(0);
18345f757f3fSDimitry Andric   BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(X86::TEST32rr))
18355f757f3fSDimitry Andric       .addReg(Sel.getCondReg())
18365f757f3fSDimitry Andric       .addReg(Sel.getCondReg());
18375f757f3fSDimitry Andric 
18385f757f3fSDimitry Andric   unsigned OpCmp;
18395f757f3fSDimitry Andric   LLT Ty = MRI.getType(DstReg);
18405f757f3fSDimitry Andric   switch (Ty.getSizeInBits()) {
18415f757f3fSDimitry Andric   default:
18425f757f3fSDimitry Andric     return false;
18435f757f3fSDimitry Andric   case 8:
18445f757f3fSDimitry Andric     OpCmp = X86::CMOV_GR8;
18455f757f3fSDimitry Andric     break;
18465f757f3fSDimitry Andric   case 16:
18475f757f3fSDimitry Andric     OpCmp = STI.canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
18485f757f3fSDimitry Andric     break;
18495f757f3fSDimitry Andric   case 32:
18505f757f3fSDimitry Andric     OpCmp = STI.canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
18515f757f3fSDimitry Andric     break;
18525f757f3fSDimitry Andric   case 64:
18535f757f3fSDimitry Andric     assert(STI.is64Bit() && STI.canUseCMOV());
18545f757f3fSDimitry Andric     OpCmp = X86::CMOV64rr;
18555f757f3fSDimitry Andric     break;
18565f757f3fSDimitry Andric   }
18575f757f3fSDimitry Andric   BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(OpCmp), DstReg)
18585f757f3fSDimitry Andric       .addReg(Sel.getTrueReg())
18595f757f3fSDimitry Andric       .addReg(Sel.getFalseReg())
18605f757f3fSDimitry Andric       .addImm(X86::COND_E);
18615f757f3fSDimitry Andric 
18625f757f3fSDimitry Andric   const TargetRegisterClass *DstRC = getRegClass(Ty, DstReg, MRI);
18635f757f3fSDimitry Andric   if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
18645f757f3fSDimitry Andric     LLVM_DEBUG(dbgs() << "Failed to constrain CMOV\n");
18655f757f3fSDimitry Andric     return false;
18665f757f3fSDimitry Andric   }
18675f757f3fSDimitry Andric 
18685f757f3fSDimitry Andric   Sel.eraseFromParent();
18695f757f3fSDimitry Andric   return true;
18705f757f3fSDimitry Andric }
18715f757f3fSDimitry Andric 
18725f757f3fSDimitry Andric InstructionSelector *
18735f757f3fSDimitry Andric llvm::createX86InstructionSelector(const X86TargetMachine &TM,
1874*0fca6ea1SDimitry Andric                                    const X86Subtarget &Subtarget,
1875*0fca6ea1SDimitry Andric                                    const X86RegisterBankInfo &RBI) {
18765f757f3fSDimitry Andric   return new X86InstructionSelector(TM, Subtarget, RBI);
18775f757f3fSDimitry Andric }
1878