SystemZInstrInfo.h revision 280031
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" 19251607Sdim#include "llvm/Target/TargetInstrInfo.h" 20251607Sdim 21251607Sdim#define GET_INSTRINFO_HEADER 22251607Sdim#include "SystemZGenInstrInfo.inc" 23251607Sdim 24251607Sdimnamespace llvm { 25251607Sdim 26251607Sdimclass SystemZTargetMachine; 27251607Sdim 28251607Sdimnamespace SystemZII { 29276479Sdimenum { 30276479Sdim // See comments in SystemZInstrFormats.td. 31276479Sdim SimpleBDXLoad = (1 << 0), 32276479Sdim SimpleBDXStore = (1 << 1), 33276479Sdim Has20BitOffset = (1 << 2), 34276479Sdim HasIndex = (1 << 3), 35276479Sdim Is128Bit = (1 << 4), 36276479Sdim AccessSizeMask = (31 << 5), 37276479Sdim AccessSizeShift = 5, 38276479Sdim CCValuesMask = (15 << 10), 39276479Sdim CCValuesShift = 10, 40276479Sdim CompareZeroCCMaskMask = (15 << 14), 41276479Sdim CompareZeroCCMaskShift = 14, 42276479Sdim CCMaskFirst = (1 << 18), 43276479Sdim CCMaskLast = (1 << 19), 44276479Sdim IsLogical = (1 << 20) 45276479Sdim}; 46276479Sdimstatic inline unsigned getAccessSize(unsigned int Flags) { 47276479Sdim return (Flags & AccessSizeMask) >> AccessSizeShift; 48276479Sdim} 49276479Sdimstatic inline unsigned getCCValues(unsigned int Flags) { 50276479Sdim return (Flags & CCValuesMask) >> CCValuesShift; 51276479Sdim} 52276479Sdimstatic inline unsigned getCompareZeroCCMask(unsigned int Flags) { 53276479Sdim return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift; 54276479Sdim} 55261991Sdim 56276479Sdim// SystemZ MachineOperand target flags. 57276479Sdimenum { 58276479Sdim // Masks out the bits for the access model. 59276479Sdim MO_SYMBOL_MODIFIER = (1 << 0), 60251607Sdim 61276479Sdim // @GOT (aka @GOTENT) 62276479Sdim MO_GOT = (1 << 0) 63276479Sdim}; 64276479Sdim// Classifies a branch. 65276479Sdimenum BranchType { 66276479Sdim // An instruction that branches on the current value of CC. 67276479Sdim BranchNormal, 68261991Sdim 69276479Sdim // An instruction that peforms a 32-bit signed comparison and branches 70276479Sdim // on the result. 71276479Sdim BranchC, 72261991Sdim 73276479Sdim // An instruction that peforms a 32-bit unsigned comparison and branches 74276479Sdim // on the result. 75276479Sdim BranchCL, 76261991Sdim 77276479Sdim // An instruction that peforms a 64-bit signed comparison and branches 78276479Sdim // on the result. 79276479Sdim BranchCG, 80261991Sdim 81276479Sdim // An instruction that peforms a 64-bit unsigned comparison and branches 82276479Sdim // on the result. 83276479Sdim BranchCLG, 84261991Sdim 85276479Sdim // An instruction that decrements a 32-bit register and branches if 86276479Sdim // the result is nonzero. 87276479Sdim BranchCT, 88261991Sdim 89276479Sdim // An instruction that decrements a 64-bit register and branches if 90276479Sdim // the result is nonzero. 91276479Sdim BranchCTG 92276479Sdim}; 93276479Sdim// Information about a branch instruction. 94276479Sdimstruct Branch { 95276479Sdim // The type of the branch. 96276479Sdim BranchType Type; 97261991Sdim 98276479Sdim // CCMASK_<N> is set if CC might be equal to N. 99276479Sdim unsigned CCValid; 100261991Sdim 101276479Sdim // CCMASK_<N> is set if the branch should be taken when CC == N. 102276479Sdim unsigned CCMask; 103261991Sdim 104276479Sdim // The target of the branch. 105276479Sdim const MachineOperand *Target; 106261991Sdim 107276479Sdim Branch(BranchType type, unsigned ccValid, unsigned ccMask, 108276479Sdim const MachineOperand *target) 109276479Sdim : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {} 110276479Sdim}; 111276479Sdim} // end namespace SystemZII 112251607Sdim 113276479Sdimclass SystemZSubtarget; 114251607Sdimclass SystemZInstrInfo : public SystemZGenInstrInfo { 115251607Sdim const SystemZRegisterInfo RI; 116276479Sdim SystemZSubtarget &STI; 117251607Sdim 118251607Sdim void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const; 119251607Sdim void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const; 120261991Sdim void expandRIPseudo(MachineInstr *MI, unsigned LowOpcode, 121261991Sdim unsigned HighOpcode, bool ConvertHigh) const; 122261991Sdim void expandRIEPseudo(MachineInstr *MI, unsigned LowOpcode, 123261991Sdim unsigned LowOpcodeK, unsigned HighOpcode) const; 124261991Sdim void expandRXYPseudo(MachineInstr *MI, unsigned LowOpcode, 125261991Sdim unsigned HighOpcode) const; 126261991Sdim void expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode, 127261991Sdim unsigned Size) const; 128261991Sdim void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 129261991Sdim DebugLoc DL, unsigned DestReg, unsigned SrcReg, 130261991Sdim unsigned LowLowOpcode, unsigned Size, bool KillSrc) const; 131261991Sdim virtual void anchor(); 132261991Sdim 133251607Sdimpublic: 134276479Sdim explicit SystemZInstrInfo(SystemZSubtarget &STI); 135251607Sdim 136251607Sdim // Override TargetInstrInfo. 137276479Sdim unsigned isLoadFromStackSlot(const MachineInstr *MI, 138276479Sdim int &FrameIndex) const override; 139276479Sdim unsigned isStoreToStackSlot(const MachineInstr *MI, 140276479Sdim int &FrameIndex) const override; 141276479Sdim bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex, 142276479Sdim int &SrcFrameIndex) const override; 143276479Sdim bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 144276479Sdim MachineBasicBlock *&FBB, 145276479Sdim SmallVectorImpl<MachineOperand> &Cond, 146276479Sdim bool AllowModify) const override; 147276479Sdim unsigned RemoveBranch(MachineBasicBlock &MBB) const override; 148276479Sdim unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 149276479Sdim MachineBasicBlock *FBB, 150276479Sdim const SmallVectorImpl<MachineOperand> &Cond, 151276479Sdim DebugLoc DL) const override; 152261991Sdim bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, 153276479Sdim unsigned &SrcReg2, int &Mask, int &Value) const override; 154261991Sdim bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, 155261991Sdim unsigned SrcReg2, int Mask, int Value, 156276479Sdim const MachineRegisterInfo *MRI) const override; 157276479Sdim bool isPredicable(MachineInstr *MI) const override; 158276479Sdim bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 159276479Sdim unsigned ExtraPredCycles, 160276479Sdim const BranchProbability &Probability) const override; 161276479Sdim bool isProfitableToIfCvt(MachineBasicBlock &TMBB, 162276479Sdim unsigned NumCyclesT, unsigned ExtraPredCyclesT, 163276479Sdim MachineBasicBlock &FMBB, 164276479Sdim unsigned NumCyclesF, unsigned ExtraPredCyclesF, 165276479Sdim const BranchProbability &Probability) const override; 166276479Sdim bool PredicateInstruction(MachineInstr *MI, 167276479Sdim const SmallVectorImpl<MachineOperand> &Pred) const 168276479Sdim override; 169276479Sdim void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 170276479Sdim DebugLoc DL, unsigned DestReg, unsigned SrcReg, 171276479Sdim bool KillSrc) const override; 172276479Sdim void storeRegToStackSlot(MachineBasicBlock &MBB, 173276479Sdim MachineBasicBlock::iterator MBBI, 174276479Sdim unsigned SrcReg, bool isKill, int FrameIndex, 175276479Sdim const TargetRegisterClass *RC, 176276479Sdim const TargetRegisterInfo *TRI) const override; 177276479Sdim void loadRegFromStackSlot(MachineBasicBlock &MBB, 178276479Sdim MachineBasicBlock::iterator MBBI, 179276479Sdim unsigned DestReg, int FrameIdx, 180276479Sdim const TargetRegisterClass *RC, 181276479Sdim const TargetRegisterInfo *TRI) const override; 182276479Sdim MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, 183276479Sdim MachineBasicBlock::iterator &MBBI, 184276479Sdim LiveVariables *LV) const override; 185276479Sdim MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 186276479Sdim const SmallVectorImpl<unsigned> &Ops, 187276479Sdim int FrameIndex) const override; 188276479Sdim MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, 189276479Sdim const SmallVectorImpl<unsigned> &Ops, 190276479Sdim MachineInstr* LoadMI) const override; 191276479Sdim bool expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const override; 192276479Sdim bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const 193276479Sdim override; 194251607Sdim 195251607Sdim // Return the SystemZRegisterInfo, which this class owns. 196251607Sdim const SystemZRegisterInfo &getRegisterInfo() const { return RI; } 197251607Sdim 198261991Sdim // Return the size in bytes of MI. 199261991Sdim uint64_t getInstSizeInBytes(const MachineInstr *MI) const; 200261991Sdim 201251607Sdim // Return true if MI is a conditional or unconditional branch. 202251607Sdim // When returning true, set Cond to the mask of condition-code 203251607Sdim // values on which the instruction will branch, and set Target 204251607Sdim // to the operand that contains the branch target. This target 205251607Sdim // can be a register or a basic block. 206261991Sdim SystemZII::Branch getBranchInfo(const MachineInstr *MI) const; 207251607Sdim 208251607Sdim // Get the load and store opcodes for a given register class. 209251607Sdim void getLoadStoreOpcodes(const TargetRegisterClass *RC, 210251607Sdim unsigned &LoadOpcode, unsigned &StoreOpcode) const; 211251607Sdim 212251607Sdim // Opcode is the opcode of an instruction that has an address operand, 213251607Sdim // and the caller wants to perform that instruction's operation on an 214251607Sdim // address that has displacement Offset. Return the opcode of a suitable 215251607Sdim // instruction (which might be Opcode itself) or 0 if no such instruction 216251607Sdim // exists. 217251607Sdim unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const; 218251607Sdim 219261991Sdim // If Opcode is a load instruction that has a LOAD AND TEST form, 220261991Sdim // return the opcode for the testing form, otherwise return 0. 221261991Sdim unsigned getLoadAndTest(unsigned Opcode) const; 222261991Sdim 223261991Sdim // Return true if ROTATE AND ... SELECTED BITS can be used to select bits 224261991Sdim // Mask of the R2 operand, given that only the low BitSize bits of Mask are 225261991Sdim // significant. Set Start and End to the I3 and I4 operands if so. 226261991Sdim bool isRxSBGMask(uint64_t Mask, unsigned BitSize, 227261991Sdim unsigned &Start, unsigned &End) const; 228261991Sdim 229261991Sdim // If Opcode is a COMPARE opcode for which an associated COMPARE AND 230261991Sdim // BRANCH exists, return the opcode for the latter, otherwise return 0. 231261991Sdim // MI, if nonnull, is the compare instruction. 232261991Sdim unsigned getCompareAndBranch(unsigned Opcode, 233276479Sdim const MachineInstr *MI = nullptr) const; 234261991Sdim 235251607Sdim // Emit code before MBBI in MI to move immediate value Value into 236251607Sdim // physical register Reg. 237251607Sdim void loadImmediate(MachineBasicBlock &MBB, 238251607Sdim MachineBasicBlock::iterator MBBI, 239251607Sdim unsigned Reg, uint64_t Value) const; 240251607Sdim}; 241251607Sdim} // end namespace llvm 242251607Sdim 243251607Sdim#endif 244