Implement branch analysis in the MBlaze backend.
[oota-llvm.git] / lib / Target / MBlaze / MBlazeInstrInfo.h
1 //===- MBlazeInstrInfo.h - MBlaze 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 MBlaze implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef MBLAZEINSTRUCTIONINFO_H
15 #define MBLAZEINSTRUCTIONINFO_H
16
17 #include "MBlaze.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Target/TargetInstrInfo.h"
20 #include "MBlazeRegisterInfo.h"
21
22 namespace llvm {
23
24 namespace MBlaze {
25
26   // MBlaze Branch Codes
27   enum FPBranchCode {
28     BRANCH_F,
29     BRANCH_T,
30     BRANCH_FL,
31     BRANCH_TL,
32     BRANCH_INVALID
33   };
34
35   // MBlaze Condition Codes
36   enum CondCode {
37     // To be used with float branch True
38     FCOND_F,
39     FCOND_UN,
40     FCOND_EQ,
41     FCOND_UEQ,
42     FCOND_OLT,
43     FCOND_ULT,
44     FCOND_OLE,
45     FCOND_ULE,
46     FCOND_SF,
47     FCOND_NGLE,
48     FCOND_SEQ,
49     FCOND_NGL,
50     FCOND_LT,
51     FCOND_NGE,
52     FCOND_LE,
53     FCOND_NGT,
54
55     // To be used with float branch False
56     // This conditions have the same mnemonic as the
57     // above ones, but are used with a branch False;
58     FCOND_T,
59     FCOND_OR,
60     FCOND_NEQ,
61     FCOND_OGL,
62     FCOND_UGE,
63     FCOND_OGE,
64     FCOND_UGT,
65     FCOND_OGT,
66     FCOND_ST,
67     FCOND_GLE,
68     FCOND_SNE,
69     FCOND_GL,
70     FCOND_NLT,
71     FCOND_GE,
72     FCOND_NLE,
73     FCOND_GT,
74
75     // Only integer conditions
76     COND_EQ,
77     COND_GT,
78     COND_GE,
79     COND_LT,
80     COND_LE,
81     COND_NE,
82     COND_INVALID
83   };
84
85   // Turn condition code into conditional branch opcode.
86   inline static unsigned GetCondBranchFromCond(CondCode CC) {
87     switch (CC) {
88     default: llvm_unreachable("Unknown condition code");
89     case COND_EQ: return MBlaze::BEQID;
90     case COND_NE: return MBlaze::BNEID;
91     case COND_GT: return MBlaze::BGTID;
92     case COND_GE: return MBlaze::BGEID;
93     case COND_LT: return MBlaze::BLTID;
94     case COND_LE: return MBlaze::BLEID;
95     }
96   }
97
98   /// GetOppositeBranchCondition - Return the inverse of the specified cond,
99   /// e.g. turning COND_E to COND_NE.
100   // CondCode GetOppositeBranchCondition(MBlaze::CondCode CC);
101
102   /// MBlazeCCToString - Map each FP condition code to its string
103   inline static const char *MBlazeFCCToString(MBlaze::CondCode CC) {
104     switch (CC) {
105     default: llvm_unreachable("Unknown condition code");
106     case FCOND_F:
107     case FCOND_T:   return "f";
108     case FCOND_UN:
109     case FCOND_OR:  return "un";
110     case FCOND_EQ:
111     case FCOND_NEQ: return "eq";
112     case FCOND_UEQ:
113     case FCOND_OGL: return "ueq";
114     case FCOND_OLT:
115     case FCOND_UGE: return "olt";
116     case FCOND_ULT:
117     case FCOND_OGE: return "ult";
118     case FCOND_OLE:
119     case FCOND_UGT: return "ole";
120     case FCOND_ULE:
121     case FCOND_OGT: return "ule";
122     case FCOND_SF:
123     case FCOND_ST:  return "sf";
124     case FCOND_NGLE:
125     case FCOND_GLE: return "ngle";
126     case FCOND_SEQ:
127     case FCOND_SNE: return "seq";
128     case FCOND_NGL:
129     case FCOND_GL:  return "ngl";
130     case FCOND_LT:
131     case FCOND_NLT: return "lt";
132     case FCOND_NGE:
133     case FCOND_GE:  return "ge";
134     case FCOND_LE:
135     case FCOND_NLE: return "nle";
136     case FCOND_NGT:
137     case FCOND_GT:  return "gt";
138     }
139   }
140
141   inline static bool isUncondBranchOpcode(int Opc) {
142     switch (Opc) {
143     default: return false;
144     case MBlaze::BRI:
145     case MBlaze::BRAI:
146     case MBlaze::BRID:
147     case MBlaze::BRAID:
148       return true;
149     }
150   }
151
152   inline static bool isCondBranchOpcode(int Opc) {
153     switch (Opc) {
154     default: return false;
155     case MBlaze::BEQI: case MBlaze::BEQID:
156     case MBlaze::BNEI: case MBlaze::BNEID:
157     case MBlaze::BGTI: case MBlaze::BGTID:
158     case MBlaze::BGEI: case MBlaze::BGEID:
159     case MBlaze::BLTI: case MBlaze::BLTID:
160     case MBlaze::BLEI: case MBlaze::BLEID:
161       return true;
162     }
163   }
164 }
165
166 /// MBlazeII - This namespace holds all of the target specific flags that
167 /// instruction info tracks.
168 ///
169 namespace MBlazeII {
170   enum {
171     // PseudoFrm - This represents an instruction that is a pseudo instruction
172     // or one that has not been implemented yet.  It is illegal to code generate
173     // it, but tolerated for intermediate implementation stages.
174     FPseudo = 0,
175     FRRR,
176     FRRI,
177     FCRR,
178     FCRI,
179     FRCR,
180     FRCI,
181     FCCR,
182     FCCI,
183     FRRCI,
184     FRRC,
185     FRCX,
186     FRCS,
187     FCRCS,
188     FCRCX,
189     FCX,
190     FCR,
191     FRIR,
192     FRRRR,
193     FRI,
194     FC,
195     FormMask = 63
196
197     //===------------------------------------------------------------------===//
198     // MBlaze Specific MachineOperand flags.
199     // MO_NO_FLAG,
200
201     /// MO_GOT - Represents the offset into the global offset table at which
202     /// the address the relocation entry symbol resides during execution.
203     // MO_GOT,
204
205     /// MO_GOT_CALL - Represents the offset into the global offset table at
206     /// which the address of a call site relocation entry symbol resides
207     /// during execution. This is different from the above since this flag
208     /// can only be present in call instructions.
209     // MO_GOT_CALL,
210
211     /// MO_GPREL - Represents the offset from the current gp value to be used
212     /// for the relocatable object file being produced.
213     // MO_GPREL,
214
215     /// MO_ABS_HILO - Represents the hi or low part of an absolute symbol
216     /// address.
217     // MO_ABS_HILO
218
219   };
220 }
221
222 class MBlazeInstrInfo : public TargetInstrInfoImpl {
223   MBlazeTargetMachine &TM;
224   const MBlazeRegisterInfo RI;
225 public:
226   explicit MBlazeInstrInfo(MBlazeTargetMachine &TM);
227
228   /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
229   /// such, whenever a client has an instance of instruction info, it should
230   /// always be able to get register info as well (through this method).
231   ///
232   virtual const MBlazeRegisterInfo &getRegisterInfo() const { return RI; }
233
234   /// isLoadFromStackSlot - If the specified machine instruction is a direct
235   /// load from a stack slot, return the virtual or physical register number of
236   /// the destination along with the FrameIndex of the loaded stack slot.  If
237   /// not, return 0.  This predicate must return 0 if the instruction has
238   /// any side effects other than loading from the stack slot.
239   virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
240                                        int &FrameIndex) const;
241
242   /// isStoreToStackSlot - If the specified machine instruction is a direct
243   /// store to a stack slot, return the virtual or physical register number of
244   /// the source reg along with the FrameIndex of the loaded stack slot.  If
245   /// not, return 0.  This predicate must return 0 if the instruction has
246   /// any side effects other than storing to the stack slot.
247   virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
248                                       int &FrameIndex) const;
249
250   /// Branch Analysis
251   virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
252                              MachineBasicBlock *&FBB,
253                              SmallVectorImpl<MachineOperand> &Cond,
254                              bool AllowModify) const;
255   virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
256                                 MachineBasicBlock *FBB,
257                                 const SmallVectorImpl<MachineOperand> &Cond,
258                                 DebugLoc DL) const;
259   virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
260   virtual void copyPhysReg(MachineBasicBlock &MBB,
261                            MachineBasicBlock::iterator I, DebugLoc DL,
262                            unsigned DestReg, unsigned SrcReg,
263                            bool KillSrc) const;
264   virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
265                                    MachineBasicBlock::iterator MBBI,
266                                    unsigned SrcReg, bool isKill, int FrameIndex,
267                                    const TargetRegisterClass *RC,
268                                    const TargetRegisterInfo *TRI) const;
269
270   virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
271                                     MachineBasicBlock::iterator MBBI,
272                                     unsigned DestReg, int FrameIndex,
273                                     const TargetRegisterClass *RC,
274                                     const TargetRegisterInfo *TRI) const;
275
276   /// Insert nop instruction when hazard condition is found
277   virtual void insertNoop(MachineBasicBlock &MBB,
278                           MachineBasicBlock::iterator MI) const;
279
280   /// getGlobalBaseReg - Return a virtual register initialized with the
281   /// the global base register value. Output instructions required to
282   /// initialize the register in the function entry block, if necessary.
283   ///
284   unsigned getGlobalBaseReg(MachineFunction *MF) const;
285 };
286
287 }
288
289 #endif