[SystemZ] Use MVC to spill loads and stores
[oota-llvm.git] / lib / Target / SystemZ / SystemZInstrInfo.h
1 //===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the SystemZ implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TARGET_SYSTEMZINSTRINFO_H
15 #define LLVM_TARGET_SYSTEMZINSTRINFO_H
16
17 #include "SystemZ.h"
18 #include "SystemZRegisterInfo.h"
19 #include "llvm/Target/TargetInstrInfo.h"
20
21 #define GET_INSTRINFO_HEADER
22 #include "SystemZGenInstrInfo.inc"
23
24 namespace llvm {
25
26 class SystemZTargetMachine;
27
28 namespace SystemZII {
29   enum {
30     // See comments in SystemZInstrFormats.td.
31     SimpleBDXLoad  = (1 << 0),
32     SimpleBDXStore = (1 << 1),
33     Has20BitOffset = (1 << 2),
34     HasIndex       = (1 << 3),
35     Is128Bit       = (1 << 4)
36   };
37   // SystemZ MachineOperand target flags.
38   enum {
39     // Masks out the bits for the access model.
40     MO_SYMBOL_MODIFIER = (1 << 0),
41
42     // @GOT (aka @GOTENT)
43     MO_GOT = (1 << 0)
44   };
45   // Classifies a branch.
46   enum BranchType {
47     // An instruction that branches on the current value of CC.
48     BranchNormal,
49
50     // An instruction that peforms a 32-bit signed comparison and branches
51     // on the result.
52     BranchC,
53
54     // An instruction that peforms a 64-bit signed comparison and branches
55     // on the result.
56     BranchCG
57   };
58   // Information about a branch instruction.
59   struct Branch {
60     // The type of the branch.
61     BranchType Type;
62
63     // CCMASK_<N> is set if the branch should be taken when CC == N.
64     unsigned CCMask;
65
66     // The target of the branch.
67     const MachineOperand *Target;
68
69     Branch(BranchType type, unsigned ccMask, const MachineOperand *target)
70       : Type(type), CCMask(ccMask), Target(target) {}
71   };
72 }
73
74 class SystemZInstrInfo : public SystemZGenInstrInfo {
75   const SystemZRegisterInfo RI;
76
77   void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
78   void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
79
80 public:
81   explicit SystemZInstrInfo(SystemZTargetMachine &TM);
82
83   // Override TargetInstrInfo.
84   virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
85                                        int &FrameIndex) const LLVM_OVERRIDE;
86   virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
87                                       int &FrameIndex) const LLVM_OVERRIDE;
88   virtual bool AnalyzeBranch(MachineBasicBlock &MBB,
89                              MachineBasicBlock *&TBB,
90                              MachineBasicBlock *&FBB,
91                              SmallVectorImpl<MachineOperand> &Cond,
92                              bool AllowModify) const LLVM_OVERRIDE;
93   virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const LLVM_OVERRIDE;
94   virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
95                                 MachineBasicBlock *FBB,
96                                 const SmallVectorImpl<MachineOperand> &Cond,
97                                 DebugLoc DL) const LLVM_OVERRIDE;
98   virtual void copyPhysReg(MachineBasicBlock &MBB,
99                            MachineBasicBlock::iterator MBBI, DebugLoc DL,
100                            unsigned DestReg, unsigned SrcReg,
101                            bool KillSrc) const LLVM_OVERRIDE;
102   virtual void
103     storeRegToStackSlot(MachineBasicBlock &MBB,
104                         MachineBasicBlock::iterator MBBI,
105                         unsigned SrcReg, bool isKill, int FrameIndex,
106                         const TargetRegisterClass *RC,
107                         const TargetRegisterInfo *TRI) const LLVM_OVERRIDE;
108   virtual void
109     loadRegFromStackSlot(MachineBasicBlock &MBB,
110                          MachineBasicBlock::iterator MBBI,
111                          unsigned DestReg, int FrameIdx,
112                          const TargetRegisterClass *RC,
113                          const TargetRegisterInfo *TRI) const LLVM_OVERRIDE;
114   virtual MachineInstr *
115     foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
116                           const SmallVectorImpl<unsigned> &Ops,
117                           int FrameIndex) const;
118   virtual MachineInstr *
119     foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI,
120                           const SmallVectorImpl<unsigned> &Ops,
121                           MachineInstr* LoadMI) const;
122   virtual bool
123     expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const LLVM_OVERRIDE;
124   virtual bool
125     ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
126     LLVM_OVERRIDE;
127
128   // Return the SystemZRegisterInfo, which this class owns.
129   const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
130
131   // Return the size in bytes of MI.
132   uint64_t getInstSizeInBytes(const MachineInstr *MI) const;
133
134   // Return true if MI is a conditional or unconditional branch.
135   // When returning true, set Cond to the mask of condition-code
136   // values on which the instruction will branch, and set Target
137   // to the operand that contains the branch target.  This target
138   // can be a register or a basic block.
139   SystemZII::Branch getBranchInfo(const MachineInstr *MI) const;
140
141   // Get the load and store opcodes for a given register class.
142   void getLoadStoreOpcodes(const TargetRegisterClass *RC,
143                            unsigned &LoadOpcode, unsigned &StoreOpcode) const;
144
145   // Opcode is the opcode of an instruction that has an address operand,
146   // and the caller wants to perform that instruction's operation on an
147   // address that has displacement Offset.  Return the opcode of a suitable
148   // instruction (which might be Opcode itself) or 0 if no such instruction
149   // exists.
150   unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const;
151
152   // If Opcode is a COMPARE opcode for which an associated COMPARE AND
153   // BRANCH exists, return the opcode for the latter, otherwise return 0.
154   // MI, if nonnull, is the compare instruction.
155   unsigned getCompareAndBranch(unsigned Opcode,
156                                const MachineInstr *MI = 0) const;
157
158   // Emit code before MBBI in MI to move immediate value Value into
159   // physical register Reg.
160   void loadImmediate(MachineBasicBlock &MBB,
161                      MachineBasicBlock::iterator MBBI,
162                      unsigned Reg, uint64_t Value) const;
163 };
164 } // end namespace llvm
165
166 #endif