SystemZInstrInfo.h revision 327952
1251607Sdim//===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===// 2251607Sdim// 3251607Sdim// The LLVM Compiler Infrastructure 4251607Sdim// 5251607Sdim// This file is distributed under the University of Illinois Open Source 6251607Sdim// License. See LICENSE.TXT for details. 7251607Sdim// 8251607Sdim//===----------------------------------------------------------------------===// 9251607Sdim// 10251607Sdim// This file contains the SystemZ implementation of the TargetInstrInfo class. 11251607Sdim// 12251607Sdim//===----------------------------------------------------------------------===// 13251607Sdim 14280031Sdim#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H 15280031Sdim#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H 16251607Sdim 17251607Sdim#include "SystemZ.h" 18251607Sdim#include "SystemZRegisterInfo.h" 19321369Sdim#include "llvm/ADT/ArrayRef.h" 20321369Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 21321369Sdim#include "llvm/CodeGen/MachineFunction.h" 22321369Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 23327952Sdim#include "llvm/CodeGen/TargetInstrInfo.h" 24321369Sdim#include <cstdint> 25251607Sdim 26251607Sdim#define GET_INSTRINFO_HEADER 27251607Sdim#include "SystemZGenInstrInfo.inc" 28251607Sdim 29251607Sdimnamespace llvm { 30251607Sdim 31321369Sdimclass SystemZSubtarget; 32251607Sdim 33251607Sdimnamespace SystemZII { 34321369Sdim 35276479Sdimenum { 36276479Sdim // See comments in SystemZInstrFormats.td. 37276479Sdim SimpleBDXLoad = (1 << 0), 38276479Sdim SimpleBDXStore = (1 << 1), 39276479Sdim Has20BitOffset = (1 << 2), 40276479Sdim HasIndex = (1 << 3), 41276479Sdim Is128Bit = (1 << 4), 42276479Sdim AccessSizeMask = (31 << 5), 43276479Sdim AccessSizeShift = 5, 44276479Sdim CCValuesMask = (15 << 10), 45276479Sdim CCValuesShift = 10, 46276479Sdim CompareZeroCCMaskMask = (15 << 14), 47276479Sdim CompareZeroCCMaskShift = 14, 48276479Sdim CCMaskFirst = (1 << 18), 49276479Sdim CCMaskLast = (1 << 19), 50276479Sdim IsLogical = (1 << 20) 51276479Sdim}; 52321369Sdim 53276479Sdimstatic inline unsigned getAccessSize(unsigned int Flags) { 54276479Sdim return (Flags & AccessSizeMask) >> AccessSizeShift; 55276479Sdim} 56321369Sdim 57276479Sdimstatic inline unsigned getCCValues(unsigned int Flags) { 58276479Sdim return (Flags & CCValuesMask) >> CCValuesShift; 59276479Sdim} 60321369Sdim 61276479Sdimstatic inline unsigned getCompareZeroCCMask(unsigned int Flags) { 62276479Sdim return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift; 63276479Sdim} 64261991Sdim 65276479Sdim// SystemZ MachineOperand target flags. 66276479Sdimenum { 67276479Sdim // Masks out the bits for the access model. 68288943Sdim MO_SYMBOL_MODIFIER = (3 << 0), 69251607Sdim 70276479Sdim // @GOT (aka @GOTENT) 71288943Sdim MO_GOT = (1 << 0), 72288943Sdim 73288943Sdim // @INDNTPOFF 74288943Sdim MO_INDNTPOFF = (2 << 0) 75276479Sdim}; 76321369Sdim 77276479Sdim// Classifies a branch. 78276479Sdimenum BranchType { 79276479Sdim // An instruction that branches on the current value of CC. 80276479Sdim BranchNormal, 81261991Sdim 82276479Sdim // An instruction that peforms a 32-bit signed comparison and branches 83276479Sdim // on the result. 84276479Sdim BranchC, 85261991Sdim 86276479Sdim // An instruction that peforms a 32-bit unsigned comparison and branches 87276479Sdim // on the result. 88276479Sdim BranchCL, 89261991Sdim 90276479Sdim // An instruction that peforms a 64-bit signed comparison and branches 91276479Sdim // on the result. 92276479Sdim BranchCG, 93261991Sdim 94276479Sdim // An instruction that peforms a 64-bit unsigned comparison and branches 95276479Sdim // on the result. 96276479Sdim BranchCLG, 97261991Sdim 98276479Sdim // An instruction that decrements a 32-bit register and branches if 99276479Sdim // the result is nonzero. 100276479Sdim BranchCT, 101261991Sdim 102276479Sdim // An instruction that decrements a 64-bit register and branches if 103276479Sdim // the result is nonzero. 104276479Sdim BranchCTG 105276479Sdim}; 106321369Sdim 107276479Sdim// Information about a branch instruction. 108276479Sdimstruct Branch { 109276479Sdim // The type of the branch. 110276479Sdim BranchType Type; 111261991Sdim 112276479Sdim // CCMASK_<N> is set if CC might be equal to N. 113276479Sdim unsigned CCValid; 114261991Sdim 115276479Sdim // CCMASK_<N> is set if the branch should be taken when CC == N. 116276479Sdim unsigned CCMask; 117261991Sdim 118276479Sdim // The target of the branch. 119276479Sdim const MachineOperand *Target; 120261991Sdim 121276479Sdim Branch(BranchType type, unsigned ccValid, unsigned ccMask, 122276479Sdim const MachineOperand *target) 123276479Sdim : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {} 124276479Sdim}; 125321369Sdim 126309124Sdim// Kinds of fused compares in compare-and-* instructions. Together with type 127309124Sdim// of the converted compare, this identifies the compare-and-* 128309124Sdim// instruction. 129309124Sdimenum FusedCompareType { 130309124Sdim // Relative branch - CRJ etc. 131309124Sdim CompareAndBranch, 132309124Sdim 133309124Sdim // Indirect branch, used for return - CRBReturn etc. 134309124Sdim CompareAndReturn, 135309124Sdim 136309124Sdim // Indirect branch, used for sibcall - CRBCall etc. 137309124Sdim CompareAndSibcall, 138309124Sdim 139309124Sdim // Trap 140309124Sdim CompareAndTrap 141309124Sdim}; 142321369Sdim 143276479Sdim} // end namespace SystemZII 144251607Sdim 145251607Sdimclass SystemZInstrInfo : public SystemZGenInstrInfo { 146251607Sdim const SystemZRegisterInfo RI; 147276479Sdim SystemZSubtarget &STI; 148251607Sdim 149251607Sdim void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const; 150251607Sdim void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const; 151309124Sdim void expandRIPseudo(MachineInstr &MI, unsigned LowOpcode, unsigned HighOpcode, 152309124Sdim bool ConvertHigh) const; 153309124Sdim void expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode, 154261991Sdim unsigned LowOpcodeK, unsigned HighOpcode) const; 155309124Sdim void expandRXYPseudo(MachineInstr &MI, unsigned LowOpcode, 156261991Sdim unsigned HighOpcode) const; 157314564Sdim void expandLOCPseudo(MachineInstr &MI, unsigned LowOpcode, 158314564Sdim unsigned HighOpcode) const; 159314564Sdim void expandLOCRPseudo(MachineInstr &MI, unsigned LowOpcode, 160314564Sdim unsigned HighOpcode) const; 161309124Sdim void expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode, 162261991Sdim unsigned Size) const; 163309124Sdim void expandLoadStackGuard(MachineInstr *MI) const; 164321369Sdim 165321369Sdim MachineInstrBuilder 166321369Sdim emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 167321369Sdim const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, 168321369Sdim unsigned LowLowOpcode, unsigned Size, bool KillSrc, 169321369Sdim bool UndefSrc) const; 170321369Sdim 171261991Sdim virtual void anchor(); 172314564Sdim 173314564Sdimprotected: 174314564Sdim /// Commutes the operands in the given instruction by changing the operands 175314564Sdim /// order and/or changing the instruction's opcode and/or the immediate value 176314564Sdim /// operand. 177314564Sdim /// 178314564Sdim /// The arguments 'CommuteOpIdx1' and 'CommuteOpIdx2' specify the operands 179314564Sdim /// to be commuted. 180314564Sdim /// 181314564Sdim /// Do not call this method for a non-commutable instruction or 182314564Sdim /// non-commutable operands. 183314564Sdim /// Even though the instruction is commutable, the method may still 184314564Sdim /// fail to commute the operands, null pointer is returned in such cases. 185314564Sdim MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 186314564Sdim unsigned CommuteOpIdx1, 187314564Sdim unsigned CommuteOpIdx2) const override; 188314564Sdim 189251607Sdimpublic: 190276479Sdim explicit SystemZInstrInfo(SystemZSubtarget &STI); 191251607Sdim 192251607Sdim // Override TargetInstrInfo. 193309124Sdim unsigned isLoadFromStackSlot(const MachineInstr &MI, 194276479Sdim int &FrameIndex) const override; 195309124Sdim unsigned isStoreToStackSlot(const MachineInstr &MI, 196276479Sdim int &FrameIndex) const override; 197309124Sdim bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, 198276479Sdim int &SrcFrameIndex) const override; 199309124Sdim bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 200276479Sdim MachineBasicBlock *&FBB, 201276479Sdim SmallVectorImpl<MachineOperand> &Cond, 202276479Sdim bool AllowModify) const override; 203314564Sdim unsigned removeBranch(MachineBasicBlock &MBB, 204314564Sdim int *BytesRemoved = nullptr) const override; 205314564Sdim unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 206288943Sdim MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 207314564Sdim const DebugLoc &DL, 208314564Sdim int *BytesAdded = nullptr) const override; 209309124Sdim bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, 210276479Sdim unsigned &SrcReg2, int &Mask, int &Value) const override; 211309124Sdim bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, 212261991Sdim unsigned SrcReg2, int Mask, int Value, 213276479Sdim const MachineRegisterInfo *MRI) const override; 214314564Sdim bool canInsertSelect(const MachineBasicBlock&, ArrayRef<MachineOperand> Cond, 215314564Sdim unsigned, unsigned, int&, int&, int&) const override; 216314564Sdim void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 217314564Sdim const DebugLoc &DL, unsigned DstReg, 218314564Sdim ArrayRef<MachineOperand> Cond, unsigned TrueReg, 219314564Sdim unsigned FalseReg) const override; 220314564Sdim bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg, 221314564Sdim MachineRegisterInfo *MRI) const override; 222321369Sdim bool isPredicable(const MachineInstr &MI) const override; 223276479Sdim bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 224276479Sdim unsigned ExtraPredCycles, 225296417Sdim BranchProbability Probability) const override; 226276479Sdim bool isProfitableToIfCvt(MachineBasicBlock &TMBB, 227276479Sdim unsigned NumCyclesT, unsigned ExtraPredCyclesT, 228276479Sdim MachineBasicBlock &FMBB, 229276479Sdim unsigned NumCyclesF, unsigned ExtraPredCyclesF, 230296417Sdim BranchProbability Probability) const override; 231309124Sdim bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 232309124Sdim BranchProbability Probability) const override; 233309124Sdim bool PredicateInstruction(MachineInstr &MI, 234288943Sdim ArrayRef<MachineOperand> Pred) const override; 235276479Sdim void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 236309124Sdim const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, 237276479Sdim bool KillSrc) const override; 238276479Sdim void storeRegToStackSlot(MachineBasicBlock &MBB, 239276479Sdim MachineBasicBlock::iterator MBBI, 240276479Sdim unsigned SrcReg, bool isKill, int FrameIndex, 241276479Sdim const TargetRegisterClass *RC, 242276479Sdim const TargetRegisterInfo *TRI) const override; 243276479Sdim void loadRegFromStackSlot(MachineBasicBlock &MBB, 244276479Sdim MachineBasicBlock::iterator MBBI, 245276479Sdim unsigned DestReg, int FrameIdx, 246276479Sdim const TargetRegisterClass *RC, 247276479Sdim const TargetRegisterInfo *TRI) const override; 248276479Sdim MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, 249309124Sdim MachineInstr &MI, 250276479Sdim LiveVariables *LV) const override; 251309124Sdim MachineInstr * 252309124Sdim foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, 253309124Sdim ArrayRef<unsigned> Ops, 254309124Sdim MachineBasicBlock::iterator InsertPt, int FrameIndex, 255309124Sdim LiveIntervals *LIS = nullptr) const override; 256309124Sdim MachineInstr *foldMemoryOperandImpl( 257309124Sdim MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, 258309124Sdim MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI, 259309124Sdim LiveIntervals *LIS = nullptr) const override; 260309124Sdim bool expandPostRAPseudo(MachineInstr &MBBI) const override; 261314564Sdim bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const 262276479Sdim override; 263251607Sdim 264251607Sdim // Return the SystemZRegisterInfo, which this class owns. 265251607Sdim const SystemZRegisterInfo &getRegisterInfo() const { return RI; } 266251607Sdim 267261991Sdim // Return the size in bytes of MI. 268314564Sdim unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 269261991Sdim 270251607Sdim // Return true if MI is a conditional or unconditional branch. 271251607Sdim // When returning true, set Cond to the mask of condition-code 272251607Sdim // values on which the instruction will branch, and set Target 273251607Sdim // to the operand that contains the branch target. This target 274251607Sdim // can be a register or a basic block. 275309124Sdim SystemZII::Branch getBranchInfo(const MachineInstr &MI) const; 276251607Sdim 277251607Sdim // Get the load and store opcodes for a given register class. 278251607Sdim void getLoadStoreOpcodes(const TargetRegisterClass *RC, 279251607Sdim unsigned &LoadOpcode, unsigned &StoreOpcode) const; 280251607Sdim 281251607Sdim // Opcode is the opcode of an instruction that has an address operand, 282251607Sdim // and the caller wants to perform that instruction's operation on an 283251607Sdim // address that has displacement Offset. Return the opcode of a suitable 284251607Sdim // instruction (which might be Opcode itself) or 0 if no such instruction 285251607Sdim // exists. 286251607Sdim unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const; 287251607Sdim 288261991Sdim // If Opcode is a load instruction that has a LOAD AND TEST form, 289261991Sdim // return the opcode for the testing form, otherwise return 0. 290261991Sdim unsigned getLoadAndTest(unsigned Opcode) const; 291261991Sdim 292261991Sdim // Return true if ROTATE AND ... SELECTED BITS can be used to select bits 293261991Sdim // Mask of the R2 operand, given that only the low BitSize bits of Mask are 294261991Sdim // significant. Set Start and End to the I3 and I4 operands if so. 295261991Sdim bool isRxSBGMask(uint64_t Mask, unsigned BitSize, 296261991Sdim unsigned &Start, unsigned &End) const; 297261991Sdim 298309124Sdim // If Opcode is a COMPARE opcode for which an associated fused COMPARE AND * 299309124Sdim // operation exists, return the opcode for the latter, otherwise return 0. 300261991Sdim // MI, if nonnull, is the compare instruction. 301309124Sdim unsigned getFusedCompare(unsigned Opcode, 302309124Sdim SystemZII::FusedCompareType Type, 303309124Sdim const MachineInstr *MI = nullptr) const; 304261991Sdim 305314564Sdim // If Opcode is a LOAD opcode for with an associated LOAD AND TRAP 306314564Sdim // operation exists, returh the opcode for the latter, otherwise return 0. 307314564Sdim unsigned getLoadAndTrap(unsigned Opcode) const; 308314564Sdim 309251607Sdim // Emit code before MBBI in MI to move immediate value Value into 310251607Sdim // physical register Reg. 311251607Sdim void loadImmediate(MachineBasicBlock &MBB, 312251607Sdim MachineBasicBlock::iterator MBBI, 313251607Sdim unsigned Reg, uint64_t Value) const; 314314564Sdim 315314564Sdim // Sometimes, it is possible for the target to tell, even without 316314564Sdim // aliasing information, that two MIs access different memory 317314564Sdim // addresses. This function returns true if two MIs access different 318314564Sdim // memory addresses and false otherwise. 319314564Sdim bool 320314564Sdim areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb, 321314564Sdim AliasAnalysis *AA = nullptr) const override; 322251607Sdim}; 323321369Sdim 324251607Sdim} // end namespace llvm 325251607Sdim 326321369Sdim#endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H 327