be6b812a3a642d2aa17386b76c27bc2780b1e2cb
[oota-llvm.git] / include / llvm / Target / TargetInstrInfo.h
1 //===-- llvm/Target/InstrInfo.h - Target Instruction Information --*-C++-*-==//
2 //
3 // This file describes the target machine instructions to the code generator.
4 //
5 //===---------------------------------------------------------------------===//
6
7 #ifndef LLVM_TARGET_MACHINEINSTRINFO_H
8 #define LLVM_TARGET_MACHINEINSTRINFO_H
9
10 #include "Support/DataTypes.h"
11 #include <vector>
12
13 class MachineInstrDescriptor;
14 class MachineInstr;
15 class TargetMachine;
16 class Value;
17 class Instruction;
18 class Constant;
19 class Function;
20 class MachineCodeForInstruction;
21
22 //---------------------------------------------------------------------------
23 // Data types used to define information about a single machine instruction
24 //---------------------------------------------------------------------------
25
26 typedef int MachineOpCode;
27 typedef unsigned InstrSchedClass;
28
29 const MachineOpCode INVALID_MACHINE_OPCODE = -1;
30
31
32 //---------------------------------------------------------------------------
33 // struct MachineInstrDescriptor:
34 //      Predefined information about each machine instruction.
35 //      Designed to initialized statically.
36 // 
37 // class MachineInstructionInfo
38 //      Interface to description of machine instructions
39 // 
40 //---------------------------------------------------------------------------
41
42 const unsigned  M_NOP_FLAG              = 1 << 0;
43 const unsigned  M_BRANCH_FLAG           = 1 << 1;
44 const unsigned  M_CALL_FLAG             = 1 << 2;
45 const unsigned  M_RET_FLAG              = 1 << 3;
46 const unsigned  M_ARITH_FLAG            = 1 << 4;
47 const unsigned  M_CC_FLAG               = 1 << 6;
48 const unsigned  M_LOGICAL_FLAG          = 1 << 6;
49 const unsigned  M_INT_FLAG              = 1 << 7;
50 const unsigned  M_FLOAT_FLAG            = 1 << 8;
51 const unsigned  M_CONDL_FLAG            = 1 << 9;
52 const unsigned  M_LOAD_FLAG             = 1 << 10;
53 const unsigned  M_PREFETCH_FLAG         = 1 << 11;
54 const unsigned  M_STORE_FLAG            = 1 << 12;
55 const unsigned  M_DUMMY_PHI_FLAG        = 1 << 13;
56 const unsigned  M_PSEUDO_FLAG           = 1 << 14;
57
58
59 struct MachineInstrDescriptor {
60   const char *    Name;          // Assembly language mnemonic for the opcode.
61   int             numOperands;   // Number of args; -1 if variable #args
62   int             resultPos;     // Position of the result; -1 if no result
63   unsigned        maxImmedConst; // Largest +ve constant in IMMMED field or 0.
64   bool            immedIsSignExtended; // Is IMMED field sign-extended? If so,
65                                  //   smallest -ve value is -(maxImmedConst+1).
66   unsigned        numDelaySlots; // Number of delay slots after instruction
67   unsigned        latency;       // Latency in machine cycles
68   InstrSchedClass schedClass;    // enum  identifying instr sched class
69   unsigned        iclass;        // flags identifying machine instr class
70 };
71
72
73 class MachineInstrInfo {
74   const MachineInstrDescriptor* desc;   // raw array to allow static init'n
75   unsigned descSize;            // number of entries in the desc array
76   unsigned numRealOpCodes;              // number of non-dummy op codes
77   
78   MachineInstrInfo(const MachineInstrInfo &); // DO NOT IMPLEMENT
79   void operator=(const MachineInstrInfo &);   // DO NOT IMPLEMENT
80 public:
81   MachineInstrInfo(const MachineInstrDescriptor *desc, unsigned descSize,
82                    unsigned numRealOpCodes);
83   virtual ~MachineInstrInfo();
84   
85   unsigned getNumRealOpCodes()  const { return numRealOpCodes; }
86   unsigned getNumTotalOpCodes() const { return descSize; }
87   
88   /// get - Return the machine instruction descriptor that corresponds to the
89   /// specified instruction opcode.
90   ///
91   const MachineInstrDescriptor& get(MachineOpCode opCode) const {
92     assert(opCode >= 0 && opCode < (int)descSize);
93     return desc[opCode];
94   }
95
96   const char *getName(MachineOpCode opCode) const {
97     return get(opCode).Name;
98   }
99   
100   int getNumOperands(MachineOpCode opCode) const {
101     return get(opCode).numOperands;
102   }
103   
104   int getResultPos(MachineOpCode opCode) const {
105     return get(opCode).resultPos;
106   }
107   
108   unsigned getNumDelaySlots(MachineOpCode opCode) const {
109     return get(opCode).numDelaySlots;
110   }
111   
112   InstrSchedClass getSchedClass(MachineOpCode opCode) const {
113     return get(opCode).schedClass;
114   }
115   
116   //
117   // Query instruction class flags according to the machine-independent
118   // flags listed above.
119   // 
120   unsigned getIClass(MachineOpCode opCode) const {
121     return get(opCode).iclass;
122   }
123   bool isNop(MachineOpCode opCode) const {
124     return get(opCode).iclass & M_NOP_FLAG;
125   }
126   bool isBranch(MachineOpCode opCode) const {
127     return get(opCode).iclass & M_BRANCH_FLAG;
128   }
129   bool isCall(MachineOpCode opCode) const {
130     return get(opCode).iclass & M_CALL_FLAG;
131   }
132   bool isReturn(MachineOpCode opCode) const {
133     return get(opCode).iclass & M_RET_FLAG;
134   }
135   bool isControlFlow(MachineOpCode opCode) const {
136     return get(opCode).iclass & M_BRANCH_FLAG
137         || get(opCode).iclass & M_CALL_FLAG
138         || get(opCode).iclass & M_RET_FLAG;
139   }
140   bool isArith(MachineOpCode opCode) const {
141     return get(opCode).iclass & M_ARITH_FLAG;
142   }
143   bool isCCInstr(MachineOpCode opCode) const {
144     return get(opCode).iclass & M_CC_FLAG;
145   }
146   bool isLogical(MachineOpCode opCode) const {
147     return get(opCode).iclass & M_LOGICAL_FLAG;
148   }
149   bool isIntInstr(MachineOpCode opCode) const {
150     return get(opCode).iclass & M_INT_FLAG;
151   }
152   bool isFloatInstr(MachineOpCode opCode) const {
153     return get(opCode).iclass & M_FLOAT_FLAG;
154   }
155   bool isConditional(MachineOpCode opCode) const { 
156     return get(opCode).iclass & M_CONDL_FLAG;
157   }
158   bool isLoad(MachineOpCode opCode) const {
159     return get(opCode).iclass & M_LOAD_FLAG;
160   }
161   bool isPrefetch(MachineOpCode opCode) const {
162     return get(opCode).iclass & M_PREFETCH_FLAG;
163   }
164   bool isLoadOrPrefetch(MachineOpCode opCode) const {
165     return get(opCode).iclass & M_LOAD_FLAG
166         || get(opCode).iclass & M_PREFETCH_FLAG;
167   }
168   bool isStore(MachineOpCode opCode) const {
169     return get(opCode).iclass & M_STORE_FLAG;
170   }
171   bool isMemoryAccess(MachineOpCode opCode) const {
172     return get(opCode).iclass & M_LOAD_FLAG
173         || get(opCode).iclass & M_PREFETCH_FLAG
174         || get(opCode).iclass & M_STORE_FLAG;
175   }
176   bool isDummyPhiInstr(const MachineOpCode opCode) const {
177     return get(opCode).iclass & M_DUMMY_PHI_FLAG;
178   }
179   bool isPseudoInstr(const MachineOpCode opCode) const {
180     return get(opCode).iclass & M_PSEUDO_FLAG;
181   }
182
183   // Check if an instruction can be issued before its operands are ready,
184   // or if a subsequent instruction that uses its result can be issued
185   // before the results are ready.
186   // Default to true since most instructions on many architectures allow this.
187   // 
188   virtual bool hasOperandInterlock(MachineOpCode opCode) const {
189     return true;
190   }
191   
192   virtual bool hasResultInterlock(MachineOpCode opCode) const {
193     return true;
194   }
195   
196   // 
197   // Latencies for individual instructions and instruction pairs
198   // 
199   virtual int minLatency(MachineOpCode opCode) const {
200     return get(opCode).latency;
201   }
202   
203   virtual int maxLatency(MachineOpCode opCode) const {
204     return get(opCode).latency;
205   }
206
207   //
208   // Which operand holds an immediate constant?  Returns -1 if none
209   // 
210   virtual int getImmedConstantPos(MachineOpCode opCode) const {
211     return -1; // immediate position is machine specific, so say -1 == "none"
212   }
213   
214   // Check if the specified constant fits in the immediate field
215   // of this machine instruction
216   // 
217   virtual bool constantFitsInImmedField(MachineOpCode opCode,
218                                         int64_t intValue) const;
219   
220   // Return the largest +ve constant that can be held in the IMMMED field
221   // of this machine instruction.
222   // isSignExtended is set to true if the value is sign-extended before use
223   // (this is true for all immediate fields in SPARC instructions).
224   // Return 0 if the instruction has no IMMED field.
225   // 
226   virtual uint64_t maxImmedConstant(MachineOpCode opCode,
227                                     bool &isSignExtended) const {
228     isSignExtended = get(opCode).immedIsSignExtended;
229     return get(opCode).maxImmedConst;
230   }
231
232   //-------------------------------------------------------------------------
233   // Queries about representation of LLVM quantities (e.g., constants)
234   //-------------------------------------------------------------------------
235
236   /// ConstantTypeMustBeLoaded - Test if this type of constant must be loaded
237   /// from memory into a register, i.e., cannot be set bitwise in register and
238   /// cannot use immediate fields of instructions.  Note that this only makes
239   /// sense for primitive types.
240   ///
241   virtual bool ConstantTypeMustBeLoaded(const Constant* CV) const;
242
243   // Test if this constant may not fit in the immediate field of the
244   // machine instructions (probably) generated for this instruction.
245   // 
246   virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
247                                              const Instruction* I) const {
248     return true;                        // safe but very conservative
249   }
250
251   //-------------------------------------------------------------------------
252   // Code generation support for creating individual machine instructions
253   //-------------------------------------------------------------------------
254
255   // Get certain common op codes for the current target.  this and all the
256   // Create* methods below should be moved to a machine code generation class
257   // 
258   virtual MachineOpCode getNOPOpCode() const = 0;
259
260   // Create an instruction sequence to put the constant `val' into
261   // the virtual register `dest'.  `val' may be a Constant or a
262   // GlobalValue, viz., the constant address of a global variable or function.
263   // The generated instructions are returned in `mvec'.
264   // Any temp. registers (TmpInstruction) created are recorded in mcfi.
265   // Symbolic constants or constants that must be accessed from memory
266   // are added to the constant pool via MachineFunction::get(F).
267   // 
268   virtual void  CreateCodeToLoadConst(const TargetMachine& target,
269                                       Function* F,
270                                       Value* val,
271                                       Instruction* dest,
272                                       std::vector<MachineInstr*>& mvec,
273                                       MachineCodeForInstruction& mcfi) const=0;
274   
275   // Create an instruction sequence to copy an integer value `val'
276   // to a floating point value `dest' by copying to memory and back.
277   // val must be an integral type.  dest must be a Float or Double.
278   // The generated instructions are returned in `mvec'.
279   // Any temp. registers (TmpInstruction) created are recorded in mcfi.
280   // Any stack space required is allocated via mcff.
281   // 
282   virtual void  CreateCodeToCopyIntToFloat(const TargetMachine& target,
283                                        Function* F,
284                                        Value* val,
285                                        Instruction* dest,
286                                        std::vector<MachineInstr*>& mvec,
287                                        MachineCodeForInstruction& mcfi)const=0;
288
289   // Similarly, create an instruction sequence to copy an FP value
290   // `val' to an integer value `dest' by copying to memory and back.
291   // The generated instructions are returned in `mvec'.
292   // Any temp. registers (TmpInstruction) created are recorded in mcfi.
293   // Any stack space required is allocated via mcff.
294   // 
295   virtual void  CreateCodeToCopyFloatToInt(const TargetMachine& target,
296                                        Function* F,
297                                        Value* val,
298                                        Instruction* dest,
299                                        std::vector<MachineInstr*>& mvec,
300                                        MachineCodeForInstruction& mcfi)const=0;
301   
302   // Create instruction(s) to copy src to dest, for arbitrary types
303   // The generated instructions are returned in `mvec'.
304   // Any temp. registers (TmpInstruction) created are recorded in mcfi.
305   // Any stack space required is allocated via mcff.
306   // 
307   virtual void CreateCopyInstructionsByType(const TargetMachine& target,
308                                        Function* F,
309                                        Value* src,
310                                        Instruction* dest,
311                                        std::vector<MachineInstr*>& mvec,
312                                        MachineCodeForInstruction& mcfi)const=0;
313
314   // Create instruction sequence to produce a sign-extended register value
315   // from an arbitrary sized value (sized in bits, not bytes).
316   // The generated instructions are appended to `mvec'.
317   // Any temp. registers (TmpInstruction) created are recorded in mcfi.
318   // Any stack space required is allocated via mcff.
319   // 
320   virtual void CreateSignExtensionInstructions(const TargetMachine& target,
321                                        Function* F,
322                                        Value* srcVal,
323                                        Value* destVal,
324                                        unsigned numLowBits,
325                                        std::vector<MachineInstr*>& mvec,
326                                        MachineCodeForInstruction& mcfi) const=0;
327
328   // Create instruction sequence to produce a zero-extended register value
329   // from an arbitrary sized value (sized in bits, not bytes).
330   // The generated instructions are appended to `mvec'.
331   // Any temp. registers (TmpInstruction) created are recorded in mcfi.
332   // Any stack space required is allocated via mcff.
333   // 
334   virtual void CreateZeroExtensionInstructions(const TargetMachine& target,
335                                        Function* F,
336                                        Value* srcVal,
337                                        Value* destVal,
338                                        unsigned srcSizeInBits,
339                                        std::vector<MachineInstr*>& mvec,
340                                        MachineCodeForInstruction& mcfi) const=0;
341 };
342
343 #endif