1*9880d681SAndroid Build Coastguard Worker //===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the SystemZ implementation of the TargetInstrInfo class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker #include "SystemZ.h"
18*9880d681SAndroid Build Coastguard Worker #include "SystemZRegisterInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_HEADER
22*9880d681SAndroid Build Coastguard Worker #include "SystemZGenInstrInfo.inc"
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker namespace llvm {
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker class SystemZTargetMachine;
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker namespace SystemZII {
29*9880d681SAndroid Build Coastguard Worker enum {
30*9880d681SAndroid Build Coastguard Worker // See comments in SystemZInstrFormats.td.
31*9880d681SAndroid Build Coastguard Worker SimpleBDXLoad = (1 << 0),
32*9880d681SAndroid Build Coastguard Worker SimpleBDXStore = (1 << 1),
33*9880d681SAndroid Build Coastguard Worker Has20BitOffset = (1 << 2),
34*9880d681SAndroid Build Coastguard Worker HasIndex = (1 << 3),
35*9880d681SAndroid Build Coastguard Worker Is128Bit = (1 << 4),
36*9880d681SAndroid Build Coastguard Worker AccessSizeMask = (31 << 5),
37*9880d681SAndroid Build Coastguard Worker AccessSizeShift = 5,
38*9880d681SAndroid Build Coastguard Worker CCValuesMask = (15 << 10),
39*9880d681SAndroid Build Coastguard Worker CCValuesShift = 10,
40*9880d681SAndroid Build Coastguard Worker CompareZeroCCMaskMask = (15 << 14),
41*9880d681SAndroid Build Coastguard Worker CompareZeroCCMaskShift = 14,
42*9880d681SAndroid Build Coastguard Worker CCMaskFirst = (1 << 18),
43*9880d681SAndroid Build Coastguard Worker CCMaskLast = (1 << 19),
44*9880d681SAndroid Build Coastguard Worker IsLogical = (1 << 20)
45*9880d681SAndroid Build Coastguard Worker };
getAccessSize(unsigned int Flags)46*9880d681SAndroid Build Coastguard Worker static inline unsigned getAccessSize(unsigned int Flags) {
47*9880d681SAndroid Build Coastguard Worker return (Flags & AccessSizeMask) >> AccessSizeShift;
48*9880d681SAndroid Build Coastguard Worker }
getCCValues(unsigned int Flags)49*9880d681SAndroid Build Coastguard Worker static inline unsigned getCCValues(unsigned int Flags) {
50*9880d681SAndroid Build Coastguard Worker return (Flags & CCValuesMask) >> CCValuesShift;
51*9880d681SAndroid Build Coastguard Worker }
getCompareZeroCCMask(unsigned int Flags)52*9880d681SAndroid Build Coastguard Worker static inline unsigned getCompareZeroCCMask(unsigned int Flags) {
53*9880d681SAndroid Build Coastguard Worker return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;
54*9880d681SAndroid Build Coastguard Worker }
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker // SystemZ MachineOperand target flags.
57*9880d681SAndroid Build Coastguard Worker enum {
58*9880d681SAndroid Build Coastguard Worker // Masks out the bits for the access model.
59*9880d681SAndroid Build Coastguard Worker MO_SYMBOL_MODIFIER = (3 << 0),
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker // @GOT (aka @GOTENT)
62*9880d681SAndroid Build Coastguard Worker MO_GOT = (1 << 0),
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker // @INDNTPOFF
65*9880d681SAndroid Build Coastguard Worker MO_INDNTPOFF = (2 << 0)
66*9880d681SAndroid Build Coastguard Worker };
67*9880d681SAndroid Build Coastguard Worker // Classifies a branch.
68*9880d681SAndroid Build Coastguard Worker enum BranchType {
69*9880d681SAndroid Build Coastguard Worker // An instruction that branches on the current value of CC.
70*9880d681SAndroid Build Coastguard Worker BranchNormal,
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker // An instruction that peforms a 32-bit signed comparison and branches
73*9880d681SAndroid Build Coastguard Worker // on the result.
74*9880d681SAndroid Build Coastguard Worker BranchC,
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker // An instruction that peforms a 32-bit unsigned comparison and branches
77*9880d681SAndroid Build Coastguard Worker // on the result.
78*9880d681SAndroid Build Coastguard Worker BranchCL,
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker // An instruction that peforms a 64-bit signed comparison and branches
81*9880d681SAndroid Build Coastguard Worker // on the result.
82*9880d681SAndroid Build Coastguard Worker BranchCG,
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker // An instruction that peforms a 64-bit unsigned comparison and branches
85*9880d681SAndroid Build Coastguard Worker // on the result.
86*9880d681SAndroid Build Coastguard Worker BranchCLG,
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker // An instruction that decrements a 32-bit register and branches if
89*9880d681SAndroid Build Coastguard Worker // the result is nonzero.
90*9880d681SAndroid Build Coastguard Worker BranchCT,
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker // An instruction that decrements a 64-bit register and branches if
93*9880d681SAndroid Build Coastguard Worker // the result is nonzero.
94*9880d681SAndroid Build Coastguard Worker BranchCTG
95*9880d681SAndroid Build Coastguard Worker };
96*9880d681SAndroid Build Coastguard Worker // Information about a branch instruction.
97*9880d681SAndroid Build Coastguard Worker struct Branch {
98*9880d681SAndroid Build Coastguard Worker // The type of the branch.
99*9880d681SAndroid Build Coastguard Worker BranchType Type;
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker // CCMASK_<N> is set if CC might be equal to N.
102*9880d681SAndroid Build Coastguard Worker unsigned CCValid;
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker // CCMASK_<N> is set if the branch should be taken when CC == N.
105*9880d681SAndroid Build Coastguard Worker unsigned CCMask;
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker // The target of the branch.
108*9880d681SAndroid Build Coastguard Worker const MachineOperand *Target;
109*9880d681SAndroid Build Coastguard Worker
BranchBranch110*9880d681SAndroid Build Coastguard Worker Branch(BranchType type, unsigned ccValid, unsigned ccMask,
111*9880d681SAndroid Build Coastguard Worker const MachineOperand *target)
112*9880d681SAndroid Build Coastguard Worker : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
113*9880d681SAndroid Build Coastguard Worker };
114*9880d681SAndroid Build Coastguard Worker // Kinds of fused compares in compare-and-* instructions. Together with type
115*9880d681SAndroid Build Coastguard Worker // of the converted compare, this identifies the compare-and-*
116*9880d681SAndroid Build Coastguard Worker // instruction.
117*9880d681SAndroid Build Coastguard Worker enum FusedCompareType {
118*9880d681SAndroid Build Coastguard Worker // Relative branch - CRJ etc.
119*9880d681SAndroid Build Coastguard Worker CompareAndBranch,
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker // Indirect branch, used for return - CRBReturn etc.
122*9880d681SAndroid Build Coastguard Worker CompareAndReturn,
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker // Indirect branch, used for sibcall - CRBCall etc.
125*9880d681SAndroid Build Coastguard Worker CompareAndSibcall,
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker // Trap
128*9880d681SAndroid Build Coastguard Worker CompareAndTrap
129*9880d681SAndroid Build Coastguard Worker };
130*9880d681SAndroid Build Coastguard Worker } // end namespace SystemZII
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker class SystemZSubtarget;
133*9880d681SAndroid Build Coastguard Worker class SystemZInstrInfo : public SystemZGenInstrInfo {
134*9880d681SAndroid Build Coastguard Worker const SystemZRegisterInfo RI;
135*9880d681SAndroid Build Coastguard Worker SystemZSubtarget &STI;
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
138*9880d681SAndroid Build Coastguard Worker void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
139*9880d681SAndroid Build Coastguard Worker void expandRIPseudo(MachineInstr &MI, unsigned LowOpcode, unsigned HighOpcode,
140*9880d681SAndroid Build Coastguard Worker bool ConvertHigh) const;
141*9880d681SAndroid Build Coastguard Worker void expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode,
142*9880d681SAndroid Build Coastguard Worker unsigned LowOpcodeK, unsigned HighOpcode) const;
143*9880d681SAndroid Build Coastguard Worker void expandRXYPseudo(MachineInstr &MI, unsigned LowOpcode,
144*9880d681SAndroid Build Coastguard Worker unsigned HighOpcode) const;
145*9880d681SAndroid Build Coastguard Worker void expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,
146*9880d681SAndroid Build Coastguard Worker unsigned Size) const;
147*9880d681SAndroid Build Coastguard Worker void expandLoadStackGuard(MachineInstr *MI) const;
148*9880d681SAndroid Build Coastguard Worker void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
149*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
150*9880d681SAndroid Build Coastguard Worker unsigned LowLowOpcode, unsigned Size, bool KillSrc) const;
151*9880d681SAndroid Build Coastguard Worker virtual void anchor();
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker public:
154*9880d681SAndroid Build Coastguard Worker explicit SystemZInstrInfo(SystemZSubtarget &STI);
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker // Override TargetInstrInfo.
157*9880d681SAndroid Build Coastguard Worker unsigned isLoadFromStackSlot(const MachineInstr &MI,
158*9880d681SAndroid Build Coastguard Worker int &FrameIndex) const override;
159*9880d681SAndroid Build Coastguard Worker unsigned isStoreToStackSlot(const MachineInstr &MI,
160*9880d681SAndroid Build Coastguard Worker int &FrameIndex) const override;
161*9880d681SAndroid Build Coastguard Worker bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex,
162*9880d681SAndroid Build Coastguard Worker int &SrcFrameIndex) const override;
163*9880d681SAndroid Build Coastguard Worker bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
164*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&FBB,
165*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond,
166*9880d681SAndroid Build Coastguard Worker bool AllowModify) const override;
167*9880d681SAndroid Build Coastguard Worker unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
168*9880d681SAndroid Build Coastguard Worker unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
169*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
170*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL) const override;
171*9880d681SAndroid Build Coastguard Worker bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
172*9880d681SAndroid Build Coastguard Worker unsigned &SrcReg2, int &Mask, int &Value) const override;
173*9880d681SAndroid Build Coastguard Worker bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
174*9880d681SAndroid Build Coastguard Worker unsigned SrcReg2, int Mask, int Value,
175*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo *MRI) const override;
176*9880d681SAndroid Build Coastguard Worker bool isPredicable(MachineInstr &MI) const override;
177*9880d681SAndroid Build Coastguard Worker bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
178*9880d681SAndroid Build Coastguard Worker unsigned ExtraPredCycles,
179*9880d681SAndroid Build Coastguard Worker BranchProbability Probability) const override;
180*9880d681SAndroid Build Coastguard Worker bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
181*9880d681SAndroid Build Coastguard Worker unsigned NumCyclesT, unsigned ExtraPredCyclesT,
182*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &FMBB,
183*9880d681SAndroid Build Coastguard Worker unsigned NumCyclesF, unsigned ExtraPredCyclesF,
184*9880d681SAndroid Build Coastguard Worker BranchProbability Probability) const override;
185*9880d681SAndroid Build Coastguard Worker bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
186*9880d681SAndroid Build Coastguard Worker BranchProbability Probability) const override;
187*9880d681SAndroid Build Coastguard Worker bool PredicateInstruction(MachineInstr &MI,
188*9880d681SAndroid Build Coastguard Worker ArrayRef<MachineOperand> Pred) const override;
189*9880d681SAndroid Build Coastguard Worker void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
190*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
191*9880d681SAndroid Build Coastguard Worker bool KillSrc) const override;
192*9880d681SAndroid Build Coastguard Worker void storeRegToStackSlot(MachineBasicBlock &MBB,
193*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI,
194*9880d681SAndroid Build Coastguard Worker unsigned SrcReg, bool isKill, int FrameIndex,
195*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC,
196*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const override;
197*9880d681SAndroid Build Coastguard Worker void loadRegFromStackSlot(MachineBasicBlock &MBB,
198*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI,
199*9880d681SAndroid Build Coastguard Worker unsigned DestReg, int FrameIdx,
200*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC,
201*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const override;
202*9880d681SAndroid Build Coastguard Worker MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
203*9880d681SAndroid Build Coastguard Worker MachineInstr &MI,
204*9880d681SAndroid Build Coastguard Worker LiveVariables *LV) const override;
205*9880d681SAndroid Build Coastguard Worker MachineInstr *
206*9880d681SAndroid Build Coastguard Worker foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
207*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> Ops,
208*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator InsertPt, int FrameIndex,
209*9880d681SAndroid Build Coastguard Worker LiveIntervals *LIS = nullptr) const override;
210*9880d681SAndroid Build Coastguard Worker MachineInstr *foldMemoryOperandImpl(
211*9880d681SAndroid Build Coastguard Worker MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
212*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,
213*9880d681SAndroid Build Coastguard Worker LiveIntervals *LIS = nullptr) const override;
214*9880d681SAndroid Build Coastguard Worker bool expandPostRAPseudo(MachineInstr &MBBI) const override;
215*9880d681SAndroid Build Coastguard Worker bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
216*9880d681SAndroid Build Coastguard Worker override;
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker // Return the SystemZRegisterInfo, which this class owns.
getRegisterInfo()219*9880d681SAndroid Build Coastguard Worker const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Worker // Return the size in bytes of MI.
222*9880d681SAndroid Build Coastguard Worker uint64_t getInstSizeInBytes(const MachineInstr &MI) const;
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Worker // Return true if MI is a conditional or unconditional branch.
225*9880d681SAndroid Build Coastguard Worker // When returning true, set Cond to the mask of condition-code
226*9880d681SAndroid Build Coastguard Worker // values on which the instruction will branch, and set Target
227*9880d681SAndroid Build Coastguard Worker // to the operand that contains the branch target. This target
228*9880d681SAndroid Build Coastguard Worker // can be a register or a basic block.
229*9880d681SAndroid Build Coastguard Worker SystemZII::Branch getBranchInfo(const MachineInstr &MI) const;
230*9880d681SAndroid Build Coastguard Worker
231*9880d681SAndroid Build Coastguard Worker // Get the load and store opcodes for a given register class.
232*9880d681SAndroid Build Coastguard Worker void getLoadStoreOpcodes(const TargetRegisterClass *RC,
233*9880d681SAndroid Build Coastguard Worker unsigned &LoadOpcode, unsigned &StoreOpcode) const;
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker // Opcode is the opcode of an instruction that has an address operand,
236*9880d681SAndroid Build Coastguard Worker // and the caller wants to perform that instruction's operation on an
237*9880d681SAndroid Build Coastguard Worker // address that has displacement Offset. Return the opcode of a suitable
238*9880d681SAndroid Build Coastguard Worker // instruction (which might be Opcode itself) or 0 if no such instruction
239*9880d681SAndroid Build Coastguard Worker // exists.
240*9880d681SAndroid Build Coastguard Worker unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const;
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker // If Opcode is a load instruction that has a LOAD AND TEST form,
243*9880d681SAndroid Build Coastguard Worker // return the opcode for the testing form, otherwise return 0.
244*9880d681SAndroid Build Coastguard Worker unsigned getLoadAndTest(unsigned Opcode) const;
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker // Return true if ROTATE AND ... SELECTED BITS can be used to select bits
247*9880d681SAndroid Build Coastguard Worker // Mask of the R2 operand, given that only the low BitSize bits of Mask are
248*9880d681SAndroid Build Coastguard Worker // significant. Set Start and End to the I3 and I4 operands if so.
249*9880d681SAndroid Build Coastguard Worker bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
250*9880d681SAndroid Build Coastguard Worker unsigned &Start, unsigned &End) const;
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker // If Opcode is a COMPARE opcode for which an associated fused COMPARE AND *
253*9880d681SAndroid Build Coastguard Worker // operation exists, return the opcode for the latter, otherwise return 0.
254*9880d681SAndroid Build Coastguard Worker // MI, if nonnull, is the compare instruction.
255*9880d681SAndroid Build Coastguard Worker unsigned getFusedCompare(unsigned Opcode,
256*9880d681SAndroid Build Coastguard Worker SystemZII::FusedCompareType Type,
257*9880d681SAndroid Build Coastguard Worker const MachineInstr *MI = nullptr) const;
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker // Emit code before MBBI in MI to move immediate value Value into
260*9880d681SAndroid Build Coastguard Worker // physical register Reg.
261*9880d681SAndroid Build Coastguard Worker void loadImmediate(MachineBasicBlock &MBB,
262*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI,
263*9880d681SAndroid Build Coastguard Worker unsigned Reg, uint64_t Value) const;
264*9880d681SAndroid Build Coastguard Worker };
265*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker #endif
268