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