Capture information about whether the target instructions have delay slots
[oota-llvm.git] / include / llvm / Target / TargetInstrInfo.h
1 //===-- llvm/Target/TargetInstrInfo.h - Instruction Info --------*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the target machine instructions to the code generator.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TARGET_TARGETINSTRINFO_H
15 #define LLVM_TARGET_TARGETINSTRINFO_H
16
17 #include "llvm/CodeGen/MachineBasicBlock.h"
18 #include "llvm/Support/DataTypes.h"
19 #include <vector>
20 #include <cassert>
21
22 namespace llvm {
23
24 class MachineInstr;
25 class TargetMachine;
26 class Value;
27 class Type;
28 class Instruction;
29 class Constant;
30 class Function;
31 class MachineCodeForInstruction;
32
33 //---------------------------------------------------------------------------
34 // Data types used to define information about a single machine instruction
35 //---------------------------------------------------------------------------
36
37 typedef short MachineOpCode;
38 typedef unsigned InstrSchedClass;
39
40 //---------------------------------------------------------------------------
41 // struct TargetInstrDescriptor:
42 //      Predefined information about each machine instruction.
43 //      Designed to initialized statically.
44 //
45
46 const unsigned M_NOP_FLAG               = 1 << 0;
47 const unsigned M_BRANCH_FLAG            = 1 << 1;
48 const unsigned M_CALL_FLAG              = 1 << 2;
49 const unsigned M_RET_FLAG               = 1 << 3;
50 const unsigned M_BARRIER_FLAG           = 1 << 4;
51 const unsigned M_DELAY_SLOT             = 1 << 5;
52 const unsigned M_CC_FLAG                = 1 << 6;
53 const unsigned M_LOAD_FLAG              = 1 << 10;
54 const unsigned M_STORE_FLAG             = 1 << 12;
55 // 3-addr instructions which really work like 2-addr ones, eg. X86 add/sub
56 const unsigned M_2_ADDR_FLAG           = 1 << 15;
57
58 // M_TERMINATOR_FLAG - Is this instruction part of the terminator for a basic
59 // block?  Typically this is things like return and branch instructions.
60 // Various passes use this to insert code into the bottom of a basic block, but
61 // before control flow occurs.
62 const unsigned M_TERMINATOR_FLAG       = 1 << 16;
63
64 struct TargetInstrDescriptor {
65   const char *    Name;          // Assembly language mnemonic for the opcode.
66   int             numOperands;   // Number of args; -1 if variable #args
67   int             resultPos;     // Position of the result; -1 if no result
68   unsigned        maxImmedConst; // Largest +ve constant in IMMED field or 0.
69   bool            immedIsSignExtended; // Is IMMED field sign-extended? If so,
70                                  //   smallest -ve value is -(maxImmedConst+1).
71   unsigned        numDelaySlots; // Number of delay slots after instruction
72   unsigned        latency;       // Latency in machine cycles
73   InstrSchedClass schedClass;    // enum  identifying instr sched class
74   unsigned        Flags;         // flags identifying machine instr class
75   unsigned        TSFlags;       // Target Specific Flag values
76   const unsigned *ImplicitUses;  // Registers implicitly read by this instr
77   const unsigned *ImplicitDefs;  // Registers implicitly defined by this instr
78 };
79
80
81 //---------------------------------------------------------------------------
82 /// 
83 /// TargetInstrInfo - Interface to description of machine instructions
84 /// 
85 class TargetInstrInfo {
86   const TargetInstrDescriptor* desc;    // raw array to allow static init'n
87   unsigned NumOpcodes;                  // number of entries in the desc array
88   unsigned numRealOpCodes;              // number of non-dummy op codes
89   
90   TargetInstrInfo(const TargetInstrInfo &);  // DO NOT IMPLEMENT
91   void operator=(const TargetInstrInfo &);   // DO NOT IMPLEMENT
92 public:
93   TargetInstrInfo(const TargetInstrDescriptor *desc, unsigned NumOpcodes);
94   virtual ~TargetInstrInfo();
95
96   // Invariant: All instruction sets use opcode #0 as the PHI instruction
97   enum { PHI = 0 };
98   
99   unsigned getNumOpcodes() const { return NumOpcodes; }
100   
101   /// get - Return the machine instruction descriptor that corresponds to the
102   /// specified instruction opcode.
103   ///
104   const TargetInstrDescriptor& get(MachineOpCode Opcode) const {
105     assert((unsigned)Opcode < NumOpcodes);
106     return desc[Opcode];
107   }
108
109   const char *getName(MachineOpCode Opcode) const {
110     return get(Opcode).Name;
111   }
112   
113   int getNumOperands(MachineOpCode Opcode) const {
114     return get(Opcode).numOperands;
115   }
116
117
118   InstrSchedClass getSchedClass(MachineOpCode Opcode) const {
119     return get(Opcode).schedClass;
120   }
121
122   const unsigned *getImplicitUses(MachineOpCode Opcode) const {
123     return get(Opcode).ImplicitUses;
124   }
125
126   const unsigned *getImplicitDefs(MachineOpCode Opcode) const {
127     return get(Opcode).ImplicitDefs;
128   }
129
130
131   //
132   // Query instruction class flags according to the machine-independent
133   // flags listed above.
134   // 
135   bool isReturn(MachineOpCode Opcode) const {
136     return get(Opcode).Flags & M_RET_FLAG;
137   }
138
139   bool isTwoAddrInstr(MachineOpCode Opcode) const {
140     return get(Opcode).Flags & M_2_ADDR_FLAG;
141   }
142   bool isTerminatorInstr(unsigned Opcode) const {
143     return get(Opcode).Flags & M_TERMINATOR_FLAG;
144   }
145
146   /// Return true if the instruction is a register to register move
147   /// and leave the source and dest operands in the passed parameters.
148   virtual bool isMoveInstr(const MachineInstr& MI,
149                            unsigned& sourceReg,
150                            unsigned& destReg) const {
151     return false;
152   }
153
154   /// Insert a goto (unconditional branch) sequence to TMBB, at the
155   /// end of MBB
156   virtual void insertGoto(MachineBasicBlock& MBB,
157                           MachineBasicBlock& TMBB) const {
158     assert(0 && "Target didn't implement insertGoto!");
159   }
160
161   /// Reverses the branch condition of the MachineInstr pointed by
162   /// MI. The instruction is replaced and the new MI is returned.
163   virtual MachineBasicBlock::iterator
164   reverseBranchCondition(MachineBasicBlock::iterator MI) const {
165     assert(0 && "Target didn't implement reverseBranchCondition!");
166     abort();
167     return MI;
168   }
169
170   //-------------------------------------------------------------------------
171   // Code generation support for creating individual machine instructions
172   //
173   // WARNING: These methods are Sparc specific
174   //
175   // DO NOT USE ANY OF THESE METHODS THEY ARE DEPRECATED!
176   //
177   //-------------------------------------------------------------------------
178
179   unsigned getNumDelaySlots(MachineOpCode Opcode) const {
180     return get(Opcode).numDelaySlots;
181   }
182   bool isCCInstr(MachineOpCode Opcode) const {
183     return get(Opcode).Flags & M_CC_FLAG;
184   }
185   bool isNop(MachineOpCode Opcode) const {
186     return get(Opcode).Flags & M_NOP_FLAG;
187   }
188   bool isBranch(MachineOpCode Opcode) const {
189     return get(Opcode).Flags & M_BRANCH_FLAG;
190   }
191   /// isBarrier - Returns true if the specified instruction stops control flow
192   /// from executing the instruction immediately following it.  Examples include
193   /// unconditional branches and return instructions.
194   bool isBarrier(MachineOpCode Opcode) const {
195     return get(Opcode).Flags & M_BARRIER_FLAG;
196   }
197
198   bool isCall(MachineOpCode Opcode) const {
199     return get(Opcode).Flags & M_CALL_FLAG;
200   }
201   bool isLoad(MachineOpCode Opcode) const {
202     return get(Opcode).Flags & M_LOAD_FLAG;
203   }
204   bool isStore(MachineOpCode Opcode) const {
205     return get(Opcode).Flags & M_STORE_FLAG;
206   }
207
208   /// hasDelaySlot - Returns true if the specified instruction has a delay slot
209   /// which must be filled by the code generator.
210   bool hasDelaySlot(unsigned Opcode) const {
211     return get(Opcode).Flags & M_DELAY_SLOT;
212   }
213
214   virtual bool hasResultInterlock(MachineOpCode Opcode) const {
215     return true;
216   }
217
218   // 
219   // Latencies for individual instructions and instruction pairs
220   // 
221   virtual int minLatency(MachineOpCode Opcode) const {
222     return get(Opcode).latency;
223   }
224   
225   virtual int maxLatency(MachineOpCode Opcode) const {
226     return get(Opcode).latency;
227   }
228
229   //
230   // Which operand holds an immediate constant?  Returns -1 if none
231   // 
232   virtual int getImmedConstantPos(MachineOpCode Opcode) const {
233     return -1; // immediate position is machine specific, so say -1 == "none"
234   }
235   
236   // Check if the specified constant fits in the immediate field
237   // of this machine instruction
238   // 
239   virtual bool constantFitsInImmedField(MachineOpCode Opcode,
240                                         int64_t intValue) const;
241   
242   // Return the largest positive constant that can be held in the IMMED field
243   // of this machine instruction.
244   // isSignExtended is set to true if the value is sign-extended before use
245   // (this is true for all immediate fields in SPARC instructions).
246   // Return 0 if the instruction has no IMMED field.
247   // 
248   virtual uint64_t maxImmedConstant(MachineOpCode Opcode,
249                                     bool &isSignExtended) const {
250     isSignExtended = get(Opcode).immedIsSignExtended;
251     return get(Opcode).maxImmedConst;
252   }
253 };
254
255 } // End llvm namespace
256
257 #endif