xref: /minix3/external/bsd/llvm/dist/llvm/lib/Target/SystemZ/SystemZInstrInfo.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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