1//===- PPCInstructionSelector.cpp --------------------------------*- C++ -*-==// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9/// This file implements the targeting of the InstructionSelector class for 11//===----------------------------------------------------------------------===// 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 47 /// tblgen generated 'select' implementation that is used as the initial 48 /// selector for the patterns that do not require complex C++. 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 83}
// end anonymous namespace 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" 104if (RB->
getID() == PPC::GPRRegBankID) {
106return &PPC::G8RCRegClass;
108return &PPC::GPRCRegClass;
110if (RB->
getID() == PPC::FPRRegBankID) {
112return &PPC::F4RCRegClass;
114return &PPC::F8RCRegClass;
116if (RB->
getID() == PPC::VECRegBankID) {
118return &PPC::VSRCRegClass;
120if (RB->
getID() == PPC::CRRegBankID) {
122return &PPC::CRBITRCRegClass;
124return &PPC::CRRCRegClass;
133Register DstReg =
I.getOperand(0).getReg();
142// No need to constrain SrcReg. It will get constrained when we hit another of 143// its use or its defs. 144// Copies do not have constraints. 156constbool IsStore = GenericOpc == TargetOpcode::G_STORE;
158case PPC::GPRRegBankID:
161return IsStore ? PPC::STW : PPC::LWZ;
163return IsStore ? PPC::STD : PPC::LD;
168case PPC::FPRRegBankID:
171return IsStore ? PPC::STFS : PPC::LFS;
173return IsStore ? PPC::STFD : PPC::LFD;
187if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
191constRegister DstReg =
I.getOperand(0).getReg();
192constRegister SrcReg =
I.getOperand(1).getReg();
196// For now, only handle the case for 64 bit integer. 199bool IsSingle =
MRI.getType(DstReg).getSizeInBits() == 32;
200bool IsSigned =
I.getOpcode() == TargetOpcode::G_SITOFP;
201unsigned ConvOp = IsSingle ? (IsSigned ? PPC::XSCVSXDSP : PPC::XSCVUXDSP)
202 : (IsSigned ? PPC::XSCVSXDDP : PPC::XSCVUXDDP);
214if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
218constRegister DstReg =
I.getOperand(0).getReg();
219constRegister SrcReg =
I.getOperand(1).getReg();
221Register CopyReg =
MRI.createVirtualRegister(&PPC::VSFRCRegClass);
224Register ConvReg =
MRI.createVirtualRegister(&PPC::VSFRCRegClass);
226bool IsSigned =
I.getOpcode() == TargetOpcode::G_FPTOSI;
228// single-precision is stored as double-precision on PPC in registers, so 229// always use double-precision convertions. 230unsigned ConvOp = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
243constRegister DstReg =
I.getOperand(0).getReg();
244constLLT DstTy =
MRI.getType(DstReg);
247constRegister SrcReg =
I.getOperand(1).getReg();
250assert(
MRI.getType(SrcReg).getSizeInBits() == 32 &&
"Unexpected src size!");
275// For any 32 < Num < 64, check if the Imm contains at least Num consecutive 276// zeros and return the number of bits by the left of these consecutive zeros. 280if ((HiTZ + LoLZ) >= Num)
285// Direct materialization of 64-bit constants by enumerated patterns. 286// Similar to PPCISelDAGToDAG::selectI64ImmDirect(). 287std::optional<bool> PPCInstructionSelector::selectI64ImmDirect(
MachineInstr &
I,
292unsigned TZ = llvm::countr_zero<uint64_t>(Imm);
293unsigned LZ = llvm::countl_zero<uint64_t>(Imm);
294unsigned TO = llvm::countr_one<uint64_t>(Imm);
295unsignedLO = llvm::countl_one<uint64_t>(Imm);
300// Following patterns use 1 instructions to materialize the Imm. 302// 1-1) Patterns : {zeros}{15-bit valve} 303// {ones}{15-bit valve} 308// 1-2) Patterns : {zeros}{15-bit valve}{16 zeros} 309// {ones}{15-bit valve}{16 zeros} 310if (TZ > 15 && (LZ > 32 || LO > 32))
312 .
addImm((Imm >> 16) & 0xffff)
315// Following patterns use 2 instructions to materialize the Imm. 317assert(LZ < 64 &&
"Unexpected leading zeros here.");
318// Count of ones follwing the leading zeros. 319unsigned FO = llvm::countl_one<uint64_t>(Imm << LZ);
320// 2-1) Patterns : {zeros}{31-bit value} 321// {ones}{31-bit value} 324unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
325Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
327 .
addImm((Imm >> 16) & 0xffff)
335// 2-2) Patterns : {zeros}{ones}{15-bit value}{zeros} 336// {zeros}{15-bit value}{zeros} 337// {zeros}{ones}{15-bit value} 338// {ones}{15-bit value}{zeros} 339// We can take advantage of LI's sign-extension semantics to generate leading 340// ones, and then use RLDIC to mask off the ones in both sides after rotation. 341if ((LZ + FO + TZ) > 48) {
342Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
344 .
addImm((Imm >> TZ) & 0xffff)
353// 2-3) Pattern : {zeros}{15-bit value}{ones} 354// Shift right the Imm by (48 - LZ) bits to construct a negtive 16 bits value, 355// therefore we can take advantage of LI's sign-extension semantics, and then 356// mask them off after rotation. 358// +--LZ--||-15-bit-||--TO--+ +-------------|--16-bit--+ 359// |00000001bbbbbbbbb1111111| -> |00000000000001bbbbbbbbb1| 360// +------------------------+ +------------------------+ 362// Imm (Imm >> (48 - LZ) & 0xffff) 363// +----sext-----|--16-bit--+ +clear-|-----------------+ 364// |11111111111111bbbbbbbbb1| -> |00000001bbbbbbbbb1111111| 365// +------------------------+ +------------------------+ 367// LI8: sext many leading zeros RLDICL: rotate left (48 - LZ), clear left LZ 369// Since the immediates with (LZ > 32) have been handled by previous 370// patterns, here we have (LZ <= 32) to make sure we will not shift right 371// the Imm by a negative value. 372assert(LZ <= 32 &&
"Unexpected shift value.");
373Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
375 .
addImm(Imm >> (48 - LZ) & 0xffff)
384// 2-4) Patterns : {zeros}{ones}{15-bit value}{ones} 385// {ones}{15-bit value}{ones} 386// We can take advantage of LI's sign-extension semantics to generate leading 387// ones, and then use RLDICL to mask off the ones in left sides (if required) 390// +-LZ-FO||-15-bit-||--TO--+ +-------------|--16-bit--+ 391// |00011110bbbbbbbbb1111111| -> |000000000011110bbbbbbbbb| 392// +------------------------+ +------------------------+ 394// Imm (Imm >> TO) & 0xffff 395// +----sext-----|--16-bit--+ +LZ|---------------------+ 396// |111111111111110bbbbbbbbb| -> |00011110bbbbbbbbb1111111| 397// +------------------------+ +------------------------+ 399// LI8: sext many leading zeros RLDICL: rotate left TO, clear left LZ 400if ((LZ + FO + TO) > 48) {
401Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
403 .
addImm((Imm >> TO) & 0xffff)
412// 2-5) Pattern : {32 zeros}{****}{0}{15-bit value} 413// If Hi32 is zero and the Lo16(in Lo32) can be presented as a positive 16 bit 414// value, we can use LI for Lo16 without generating leading ones then add the 416if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
417Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
427// 2-6) Patterns : {******}{49 zeros}{******} 428// {******}{49 ones}{******} 429// If the Imm contains 49 consecutive zeros/ones, it means that a total of 15 430// bits remain on both sides. Rotate right the Imm to construct an int<16> 431// value, use LI for int<16> value and then use RLDICL without mask to rotate 434// 1) findContiguousZerosAtLeast(Imm, 49) 435// +------|--zeros-|------+ +---ones--||---15 bit--+ 436// |bbbbbb0000000000aaaaaa| -> |0000000000aaaaaabbbbbb| 437// +----------------------+ +----------------------+ 440// 2) findContiguousZerosAtLeast(~Imm, 49) 441// +------|--ones--|------+ +---ones--||---15 bit--+ 442// |bbbbbb1111111111aaaaaa| -> |1111111111aaaaaabbbbbb| 443// +----------------------+ +----------------------+ 448Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
460// Following patterns use 3 instructions to materialize the Imm. 462// 3-1) Patterns : {zeros}{ones}{31-bit value}{zeros} 463// {zeros}{31-bit value}{zeros} 464// {zeros}{ones}{31-bit value} 465// {ones}{31-bit value}{zeros} 466// We can take advantage of LIS's sign-extension semantics to generate leading 467// ones, add the remaining bits with ORI, and then use RLDIC to mask off the 468// ones in both sides after rotation. 469if ((LZ + FO + TZ) > 32) {
471unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
472Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
473Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
480 .
addImm((Imm >> TZ) & 0xffff)
481 .constrainAllUses(
TII,
TRI, RBI))
489// 3-2) Pattern : {zeros}{31-bit value}{ones} 490// Shift right the Imm by (32 - LZ) bits to construct a negative 32 bits 491// value, therefore we can take advantage of LIS's sign-extension semantics, 492// add the remaining bits with ORI, and then mask them off after rotation. 493// This is similar to Pattern 2-3, please refer to the diagram there. 495// Since the immediates with (LZ > 32) have been handled by previous 496// patterns, here we have (LZ <= 32) to make sure we will not shift right 497// the Imm by a negative value. 498assert(LZ <= 32 &&
"Unexpected shift value.");
499Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
500Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
502 .
addImm((Imm >> (48 - LZ)) & 0xffff)
507 .
addImm((Imm >> (32 - LZ)) & 0xffff)
516// 3-3) Patterns : {zeros}{ones}{31-bit value}{ones} 517// {ones}{31-bit value}{ones} 518// We can take advantage of LIS's sign-extension semantics to generate leading 519// ones, add the remaining bits with ORI, and then use RLDICL to mask off the 520// ones in left sides (if required) after rotation. 521// This is similar to Pattern 2-4, please refer to the diagram there. 522if ((LZ + FO + TO) > 32) {
523Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
524Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
526 .
addImm((Imm >> (TO + 16)) & 0xffff)
531 .
addImm((Imm >> TO) & 0xffff)
540// 3-4) Patterns : High word == Low word 542// Handle the first 32 bits. 543uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
544unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
545Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
546Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
563// 3-5) Patterns : {******}{33 zeros}{******} 564// {******}{33 ones}{******} 565// If the Imm contains 33 consecutive zeros/ones, it means that a total of 31 566// bits remain on both sides. Rotate right the Imm to construct an int<32> 567// value, use LIS + ORI for int<32> value and then use RLDICL without mask to 569// This is similar to Pattern 2-6, please refer to the diagram there. 573uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
574unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
575Register TmpReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
576Register Tmp2Reg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
593// If we end up here then no instructions were inserted. 597// Derived from PPCISelDAGToDAG::selectI64Imm(). 598// TODO: Add support for prefixed instructions. 602assert(
I.getOpcode() == TargetOpcode::G_CONSTANT &&
"Unexpected G code");
604Register DstReg =
I.getOperand(0).getReg();
605 int64_t
Imm =
I.getOperand(1).getCImm()->getValue().getZExtValue();
606// No more than 3 instructions are used if we can select the i64 immediate 613// Calculate the last bits as required. 618 (Hi16 || Lo16) ?
MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
620// Handle the upper 32 bit value. 621 std::optional<bool> Res =
626// Add in the last bits as required. 629 Lo16 ?
MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
648bool PPCInstructionSelector::selectConstantPool(
653// TODO: handle 32-bit. 654// TODO: Enabling floating point constant pool selection on AIX requires 655// global isel on big endian target enabled first. 656// See CallLowering::enableBigEndian(). 657if (!STI.isPPC64() || !STI.isLittleEndian())
662constRegister DstReg =
I.getOperand(0).getReg();
663unsigned CPI =
I.getOperand(1).getIndex();
665// Address stored in the TOC entry. This is related to code model and the ABI 666// we are currently using. For now we only handle 64-bit Linux LE. PowerPC 667// only supports small, medium and large code model. 670"PowerPC doesn't support tiny or kernel code models.");
672constMCRegister TOCReg = STI.getTOCPointerRegister();
678// For now we only handle 64-bit Linux. 680// For small code model, generate LDtocCPT(CPI, X2). 686Register HaAddrReg =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
692// For large code model, generate LDtocL(CPI, ADDIStocHA8(X2, CPI)) 698// For medium code model, generate ADDItocL8(CPI, ADDIStocHA8(X2, CPI)) 709auto &
MBB = *
I.getParent();
720if (selectImpl(
I, *CoverageInfo))
723unsigned Opcode =
I.getOpcode();
728case TargetOpcode::G_LOAD:
729case TargetOpcode::G_STORE: {
739auto SelectLoadStoreAddressingMode = [&]() ->
MachineInstr * {
741I.getOpcode(), RBI.getRegBank(LdSt.
getReg(0),
MRI,
TRI)->getID(),
744if (NewOpc ==
I.getOpcode())
747// For now, simply use DForm with load/store addr as base and 0 as imm. 748// FIXME: optimize load/store with some specific address patterns. 749I.setDesc(
TII.get(NewOpc));
750Register AddrReg =
I.getOperand(1).getReg();
751bool IsKill =
I.getOperand(1).isKill();
752I.getOperand(1).ChangeToImmediate(0);
753I.addOperand(*
I.getParent()->getParent(),
755/* isImp */false, IsKill));
765case TargetOpcode::G_SITOFP:
766case TargetOpcode::G_UITOFP:
767return selectIntToFP(
I,
MBB,
MRI);
768case TargetOpcode::G_FPTOSI:
769case TargetOpcode::G_FPTOUI:
770return selectFPToInt(
I,
MBB,
MRI);
771// G_SEXT will be selected in tb-gen pattern. 772case TargetOpcode::G_ZEXT:
774case TargetOpcode::G_CONSTANT:
776case TargetOpcode::G_CONSTANT_POOL:
777return selectConstantPool(
I,
MBB,
MRI);
787returnnew PPCInstructionSelector(TM, Subtarget, RBI);
789}
// end namespace llvm unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
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.
unsigned const TargetRegisterInfo * TRI
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)
#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)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
APInt rotr(unsigned rotateAmt) const
Rotate right by rotateAmt.
Align getPointerABIAlignment(unsigned AS) const
Layout pointer alignment.
Represents any type of generic load or store.
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.
virtual bool select(MachineInstr &I)=0
Select the (possibly generic) instruction I to only use target-specific opcodes.
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
Wrapper class representing physical registers. Should be passed by value.
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...
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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ 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,...
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
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.
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.
@ Kill
The last use of a register.
Reg
All possible values of the reg field in the ModR/M byte.
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.
bool 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.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
InstructionSelector * createPPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &Subtarget, const PPCRegisterBankInfo &RBI)
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.