824363361113f9a498b98d341c813d6bc32f0f7f
[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 "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_CC_FLAG                = 1 << 6;
52 const unsigned M_LOAD_FLAG              = 1 << 10;
53 const unsigned M_STORE_FLAG             = 1 << 12;
54 const unsigned M_DUMMY_PHI_FLAG = 1 << 13;
55 const unsigned M_PSEUDO_FLAG           = 1 << 14;       // Pseudo instruction
56 // 3-addr instructions which really work like 2-addr ones, eg. X86 add/sub
57 const unsigned M_2_ADDR_FLAG           = 1 << 15;
58
59 // M_TERMINATOR_FLAG - Is this instruction part of the terminator for a basic
60 // block?  Typically this is things like return and branch instructions.
61 // Various passes use this to insert code into the bottom of a basic block, but
62 // before control flow occurs.
63 const unsigned M_TERMINATOR_FLAG       = 1 << 16;
64
65 struct TargetInstrDescriptor {
66   const char *    Name;          // Assembly language mnemonic for the opcode.
67   int             numOperands;   // Number of args; -1 if variable #args
68   int             resultPos;     // Position of the result; -1 if no result
69   unsigned        maxImmedConst; // Largest +ve constant in IMMED field or 0.
70   bool            immedIsSignExtended; // Is IMMED field sign-extended? If so,
71                                  //   smallest -ve value is -(maxImmedConst+1).
72   unsigned        numDelaySlots; // Number of delay slots after instruction
73   unsigned        latency;       // Latency in machine cycles
74   InstrSchedClass schedClass;    // enum  identifying instr sched class
75   unsigned        Flags;         // flags identifying machine instr class
76   unsigned        TSFlags;       // Target Specific Flag values
77   const unsigned *ImplicitUses;  // Registers implicitly read by this instr
78   const unsigned *ImplicitDefs;  // Registers implicitly defined by this instr
79 };
80
81
82 //---------------------------------------------------------------------------
83 /// 
84 /// TargetInstrInfo - Interface to description of machine instructions
85 /// 
86 class TargetInstrInfo {
87   const TargetInstrDescriptor* desc;    // raw array to allow static init'n
88   unsigned NumOpcodes;                  // number of entries in the desc array
89   unsigned numRealOpCodes;              // number of non-dummy op codes
90   
91   TargetInstrInfo(const TargetInstrInfo &);  // DO NOT IMPLEMENT
92   void operator=(const TargetInstrInfo &);   // DO NOT IMPLEMENT
93 public:
94   TargetInstrInfo(const TargetInstrDescriptor *desc, unsigned NumOpcodes);
95   virtual ~TargetInstrInfo();
96
97   // Invariant: All instruction sets use opcode #0 as the PHI instruction
98   enum { PHI = 0 };
99   
100   unsigned getNumOpcodes() const { return NumOpcodes; }
101   
102   /// get - Return the machine instruction descriptor that corresponds to the
103   /// specified instruction opcode.
104   ///
105   const TargetInstrDescriptor& get(MachineOpCode Opcode) const {
106     assert((unsigned)Opcode < NumOpcodes);
107     return desc[Opcode];
108   }
109
110   const char *getName(MachineOpCode Opcode) const {
111     return get(Opcode).Name;
112   }
113   
114   int getNumOperands(MachineOpCode Opcode) const {
115     return get(Opcode).numOperands;
116   }
117
118
119   InstrSchedClass getSchedClass(MachineOpCode Opcode) const {
120     return get(Opcode).schedClass;
121   }
122
123   const unsigned *getImplicitUses(MachineOpCode Opcode) const {
124     return get(Opcode).ImplicitUses;
125   }
126
127   const unsigned *getImplicitDefs(MachineOpCode Opcode) const {
128     return get(Opcode).ImplicitDefs;
129   }
130
131
132   //
133   // Query instruction class flags according to the machine-independent
134   // flags listed above.
135   // 
136   bool isReturn(MachineOpCode Opcode) const {
137     return get(Opcode).Flags & M_RET_FLAG;
138   }
139
140   bool isPseudoInstr(MachineOpCode Opcode) const {
141     return get(Opcode).Flags & M_PSEUDO_FLAG;
142   }
143   bool isTwoAddrInstr(MachineOpCode Opcode) const {
144     return get(Opcode).Flags & M_2_ADDR_FLAG;
145   }
146   bool isTerminatorInstr(unsigned Opcode) const {
147     return get(Opcode).Flags & M_TERMINATOR_FLAG;
148   }
149
150   /// Return true if the instruction is a register to register move
151   /// and leave the source and dest operands in the passed parameters.
152   virtual bool isMoveInstr(const MachineInstr& MI,
153                            unsigned& sourceReg,
154                            unsigned& destReg) const {
155     return false;
156   }
157
158   /// Insert a goto (unconditional branch) sequence to TMBB, at the
159   /// end of MBB
160   virtual void insertGoto(MachineBasicBlock& MBB,
161                           MachineBasicBlock& TMBB) const {
162     assert(0 && "Target didn't implement insertGoto!");
163   }
164
165   /// Reverses the branch condition of the MachineInstr pointed by
166   /// MI. The instruction is replaced and the new MI is returned.
167   virtual MachineBasicBlock::iterator
168   reverseBranchCondition(MachineBasicBlock::iterator MI) const {
169     assert(0 && "Target didn't implement reverseBranchCondition!");
170     abort();
171     return MI;
172   }
173
174   //-------------------------------------------------------------------------
175   // Code generation support for creating individual machine instructions
176   //
177   // WARNING: These methods are Sparc specific
178   //
179   // DO NOT USE ANY OF THESE METHODS THEY ARE DEPRECATED!
180   //
181   //-------------------------------------------------------------------------
182
183   unsigned getNumDelaySlots(MachineOpCode Opcode) const {
184     return get(Opcode).numDelaySlots;
185   }
186   bool isCCInstr(MachineOpCode Opcode) const {
187     return get(Opcode).Flags & M_CC_FLAG;
188   }
189   bool isNop(MachineOpCode Opcode) const {
190     return get(Opcode).Flags & M_NOP_FLAG;
191   }
192   bool isBranch(MachineOpCode Opcode) const {
193     return get(Opcode).Flags & M_BRANCH_FLAG;
194   }
195   /// isBarrier - Returns true if the specified instruction stops control flow
196   /// from executing the instruction immediately following it.  Examples include
197   /// unconditional branches and return instructions.
198   bool isBarrier(MachineOpCode Opcode) const {
199     return get(Opcode).Flags & M_BARRIER_FLAG;
200   }
201   bool isCall(MachineOpCode Opcode) const {
202     return get(Opcode).Flags & M_CALL_FLAG;
203   }
204   bool isLoad(MachineOpCode Opcode) const {
205     return get(Opcode).Flags & M_LOAD_FLAG;
206   }
207   bool isStore(MachineOpCode Opcode) const {
208     return get(Opcode).Flags & M_STORE_FLAG;
209   }
210   bool isDummyPhiInstr(MachineOpCode Opcode) const {
211     return get(Opcode).Flags & M_DUMMY_PHI_FLAG;
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