25#include "llvm/IR/IntrinsicsPowerPC.h"
28#define DEBUG_TYPE "ppc-gisel"
34#define GET_GLOBALISEL_PREDICATE_BITSET
35#include "PPCGenGlobalISel.inc"
36#undef GET_GLOBALISEL_PREDICATE_BITSET
74#define GET_GLOBALISEL_PREDICATES_DECL
75#include "PPCGenGlobalISel.inc"
76#undef GET_GLOBALISEL_PREDICATES_DECL
78#define GET_GLOBALISEL_TEMPORARIES_DECL
79#include "PPCGenGlobalISel.inc"
80#undef GET_GLOBALISEL_TEMPORARIES_DECL
85#define GET_GLOBALISEL_IMPL
86#include "PPCGenGlobalISel.inc"
87#undef GET_GLOBALISEL_IMPL
92 : TM(TM), STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()),
95#include
"PPCGenGlobalISel.inc"
98#include
"PPCGenGlobalISel.inc"
104 if (RB->
getID() == PPC::GPRRegBankID) {
105 if (Ty.getSizeInBits() == 64)
106 return &PPC::G8RCRegClass;
107 if (Ty.getSizeInBits() <= 32)
108 return &PPC::GPRCRegClass;
110 if (RB->
getID() == PPC::FPRRegBankID) {
111 if (Ty.getSizeInBits() == 32)
112 return &PPC::F4RCRegClass;
113 if (Ty.getSizeInBits() == 64)
114 return &PPC::F8RCRegClass;
116 if (RB->
getID() == PPC::VECRegBankID) {
117 if (Ty.getSizeInBits() == 128)
118 return &PPC::VSRCRegClass;
120 if (RB->
getID() == PPC::CRRegBankID) {
121 if (Ty.getSizeInBits() == 1)
122 return &PPC::CRBITRCRegClass;
123 if (Ty.getSizeInBits() == 4)
124 return &PPC::CRRCRegClass;
133 Register DstReg =
I.getOperand(0).getReg();
156 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
158 case PPC::GPRRegBankID:
161 return IsStore ? PPC::STW : PPC::LWZ;
163 return IsStore ? PPC::STD : PPC::LD;
168 case PPC::FPRRegBankID:
171 return IsStore ? PPC::STFS : PPC::LFS;
173 return IsStore ? PPC::STFD : PPC::LFD;
187 if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
190 const DebugLoc &DbgLoc =
I.getDebugLoc();
191 const Register DstReg =
I.getOperand(0).getReg();
192 const Register SrcReg =
I.getOperand(1).getReg();
199 bool IsSingle =
MRI.getType(DstReg).getSizeInBits() == 32;
200 bool IsSigned =
I.getOpcode() == TargetOpcode::G_SITOFP;
201 unsigned ConvOp = IsSingle ? (IsSigned ? PPC::XSCVSXDSP : PPC::XSCVUXDSP)
202 : (IsSigned ? PPC::XSCVSXDDP : PPC::XSCVUXDDP);
212bool PPCInstructionSelector::selectFPToInt(MachineInstr &
I,
213 MachineBasicBlock &
MBB,
214 MachineRegisterInfo &
MRI)
const {
215 if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
218 const DebugLoc &DbgLoc =
I.getDebugLoc();
219 const Register DstReg =
I.getOperand(0).getReg();
220 const Register SrcReg =
I.getOperand(1).getReg();
222 Register CopyReg =
MRI.createVirtualRegister(&PPC::VSFRCRegClass);
225 Register ConvReg =
MRI.createVirtualRegister(&PPC::VSFRCRegClass);
227 bool IsSigned =
I.getOpcode() == TargetOpcode::G_FPTOSI;
231 unsigned ConvOp = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
243bool PPCInstructionSelector::selectZExt(MachineInstr &
I, MachineBasicBlock &
MBB,
244 MachineRegisterInfo &
MRI)
const {
245 const Register DstReg =
I.getOperand(0).getReg();
246 const LLT DstTy =
MRI.getType(DstReg);
249 const Register SrcReg =
I.getOperand(1).getReg();
252 assert(
MRI.getType(SrcReg).getSizeInBits() == 32 &&
"Unexpected src size!");
283 if ((HiTZ + LoLZ) >= Num)
290std::optional<bool> PPCInstructionSelector::selectI64ImmDirect(MachineInstr &
I,
291 MachineBasicBlock &
MBB,
292 MachineRegisterInfo &
MRI,
294 uint64_t Imm)
const {
299 uint32_t Hi32 =
Hi_32(Imm);
300 uint32_t Lo32 =
Lo_32(Imm);
315 if (TZ > 15 && (LZ > 32 || LO > 32)) {
317 .
addImm((Imm >> 16) & 0xffff)
324 assert(LZ < 64 &&
"Unexpected leading zeros here.");
330 uint64_t ImmHi16 = (
Imm >> 16) & 0xffff;
331 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
332 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
334 .
addImm((Imm >> 16) & 0xffff)
337 .
addReg(TmpReg, RegState::Kill)
348 if ((LZ + FO + TZ) > 48) {
349 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
351 .
addImm((Imm >> TZ) & 0xffff)
354 .
addReg(TmpReg, RegState::Kill)
375 if ((LZ + TO) > 48) {
379 assert(LZ <= 32 &&
"Unexpected shift value.");
380 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
382 .
addImm(Imm >> (48 - LZ) & 0xffff)
385 .
addReg(TmpReg, RegState::Kill)
407 if ((LZ + FO + TO) > 48) {
408 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
410 .
addImm((Imm >> TO) & 0xffff)
413 .
addReg(TmpReg, RegState::Kill)
423 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
424 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
429 .
addReg(TmpReg, RegState::Kill)
454 uint64_t RotImm = APInt(64, Imm).rotr(Shift).getZExtValue();
455 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
460 .
addReg(TmpReg, RegState::Kill)
476 if ((LZ + FO + TZ) > 32) {
477 uint64_t ImmHi16 = (
Imm >> (TZ + 16)) & 0xffff;
478 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
479 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
480 Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
485 .
addReg(TmpReg, RegState::Kill)
486 .
addImm((Imm >> TZ) & 0xffff)
489 .
addReg(Tmp2Reg, RegState::Kill)
500 if ((LZ + TO) > 32) {
504 assert(LZ <= 32 &&
"Unexpected shift value.");
505 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
506 Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
508 .
addImm((Imm >> (48 - LZ)) & 0xffff)
511 .
addReg(TmpReg, RegState::Kill)
512 .
addImm((Imm >> (32 - LZ)) & 0xffff)
515 .
addReg(Tmp2Reg, RegState::Kill)
527 if ((LZ + FO + TO) > 32) {
528 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
529 Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
531 .
addImm((Imm >> (TO + 16)) & 0xffff)
534 .
addReg(TmpReg, RegState::Kill)
535 .
addImm((Imm >> TO) & 0xffff)
538 .
addReg(Tmp2Reg, RegState::Kill)
547 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
548 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
549 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
550 Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
555 .
addReg(TmpReg, RegState::Kill)
560 .
addReg(Tmp2Reg, RegState::Kill)
575 uint64_t RotImm = APInt(64, Imm).rotr(Shift).getZExtValue();
576 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
577 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
578 Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
579 Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
584 .
addReg(TmpReg, RegState::Kill)
588 .
addReg(Tmp2Reg, RegState::Kill)
601bool PPCInstructionSelector::selectI64Imm(MachineInstr &
I,
602 MachineBasicBlock &
MBB,
603 MachineRegisterInfo &
MRI)
const {
604 assert(
I.getOpcode() == TargetOpcode::G_CONSTANT &&
"Unexpected G code");
606 Register DstReg =
I.getOperand(0).getReg();
607 int64_t
Imm =
I.getOperand(1).getCImm()->getValue().getZExtValue();
616 uint32_t Hi16 = (
Lo_32(Imm) >> 16) & 0xffff;
617 uint32_t Lo16 =
Lo_32(Imm) & 0xffff;
620 (Hi16 || Lo16) ?
MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
623 std::optional<bool> Res =
631 Lo16 ?
MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
648bool PPCInstructionSelector::selectConstantPool(
649 MachineInstr &
I, MachineBasicBlock &
MBB, MachineRegisterInfo &
MRI)
const {
650 const DebugLoc &DbgLoc =
I.getDebugLoc();
662 const Register DstReg =
I.getOperand(0).getReg();
663 unsigned CPI =
I.getOperand(1).getIndex();
670 "PowerPC doesn't support tiny or kernel code models.");
677 MachineInstr *
MI =
nullptr;
686 Register HaAddrReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
709bool PPCInstructionSelector::select(MachineInstr &
I) {
721 if (selectImpl(
I, *CoverageInfo))
724 unsigned Opcode =
I.getOpcode();
729 case TargetOpcode::G_LOAD:
730 case TargetOpcode::G_STORE: {
740 auto SelectLoadStoreAddressingMode = [&]() -> MachineInstr * {
745 if (NewOpc ==
I.getOpcode())
750 I.setDesc(
TII.get(NewOpc));
751 Register AddrReg =
I.getOperand(1).getReg();
752 bool IsKill =
I.getOperand(1).isKill();
753 I.getOperand(1).ChangeToImmediate(0);
754 I.addOperand(*
I.getParent()->getParent(),
760 MachineInstr *
LoadStore = SelectLoadStoreAddressingMode();
767 case TargetOpcode::G_SITOFP:
768 case TargetOpcode::G_UITOFP:
769 return selectIntToFP(
I,
MBB,
MRI);
770 case TargetOpcode::G_FPTOSI:
771 case TargetOpcode::G_FPTOUI:
772 return selectFPToInt(
I,
MBB,
MRI);
774 case TargetOpcode::G_ZEXT:
775 return selectZExt(
I,
MBB,
MRI);
776 case TargetOpcode::G_CONSTANT:
778 case TargetOpcode::G_CONSTANT_POOL:
779 return selectConstantPool(
I,
MBB,
MRI);
789 return new PPCInstructionSelector(TM, Subtarget, RBI);
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static SDNode * selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static SDNode * selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned *InstCnt=nullptr)
static void setUsesTOCBasePtr(MachineFunction &MF)
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static uint32_t findContiguousZerosAtLeast(uint64_t Imm, unsigned Num)
static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
This file declares the targeting of the RegisterBankInfo class for PowerPC.
static StringRef getName(Value *V)
LLVM_ABI Align getPointerABIAlignment(unsigned AS) const
Layout pointer alignment.
Register getPointerReg() const
Get the source register of the pointer value.
LocationSize getMemSizeInBits() const
Returns the size in bits of the memory access.
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
TypeSize getValue() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
@ MOLoad
The memory access reads data.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
Common code between 32-bit and 64-bit PowerPC targets.
Holds all the information related to register banks.
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
TargetInstrInfo - Interface to description of machine instruction set.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
int countl_one(T Value)
Count the number of ones from the most significant bit to the first zero bit.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
InstructionSelector * createPPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &Subtarget, const PPCRegisterBankInfo &RBI)
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.