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