Convert 'struct' to 'class' in various places to adhere to the coding standards
[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_FLAG        = 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 class TargetInstrDescriptor {
65 public:
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 isTwoAddrInstr(MachineOpCode Opcode) const {
141     return get(Opcode).Flags & M_2_ADDR_FLAG;
142   }
143   bool isTerminatorInstr(unsigned Opcode) const {
144     return get(Opcode).Flags & M_TERMINATOR_FLAG;
145   }
146
147   /// Return true if the instruction is a register to register move
148   /// and leave the source and dest operands in the passed parameters.
149   virtual bool isMoveInstr(const MachineInstr& MI,
150                            unsigned& sourceReg,
151                            unsigned& destReg) const {
152     return false;
153   }
154
155   /// Insert a goto (unconditional branch) sequence to TMBB, at the
156   /// end of MBB
157   virtual void insertGoto(MachineBasicBlock& MBB,
158                           MachineBasicBlock& TMBB) const {
159     assert(0 && "Target didn't implement insertGoto!");
160   }
161
162   /// Reverses the branch condition of the MachineInstr pointed by
163   /// MI. The instruction is replaced and the new MI is returned.
164   virtual MachineBasicBlock::iterator
165   reverseBranchCondition(MachineBasicBlock::iterator MI) const {
166     assert(0 && "Target didn't implement reverseBranchCondition!");
167     abort();
168     return MI;
169   }
170
171   //-------------------------------------------------------------------------
172   // Code generation support for creating individual machine instructions
173   //
174   // WARNING: These methods are Sparc specific
175   //
176   // DO NOT USE ANY OF THESE METHODS THEY ARE DEPRECATED!
177   //
178   //-------------------------------------------------------------------------
179
180   unsigned getNumDelaySlots(MachineOpCode Opcode) const {
181     return get(Opcode).numDelaySlots;
182   }
183   bool isCCInstr(MachineOpCode Opcode) const {
184     return get(Opcode).Flags & M_CC_FLAG;
185   }
186   bool isNop(MachineOpCode Opcode) const {
187     return get(Opcode).Flags & M_NOP_FLAG;
188   }
189   bool isBranch(MachineOpCode Opcode) const {
190     return get(Opcode).Flags & M_BRANCH_FLAG;
191   }
192   /// isBarrier - Returns true if the specified instruction stops control flow
193   /// from executing the instruction immediately following it.  Examples include
194   /// unconditional branches and return instructions.
195   bool isBarrier(MachineOpCode Opcode) const {
196     return get(Opcode).Flags & M_BARRIER_FLAG;
197   }
198
199   bool isCall(MachineOpCode Opcode) const {
200     return get(Opcode).Flags & M_CALL_FLAG;
201   }
202   bool isLoad(MachineOpCode Opcode) const {
203     return get(Opcode).Flags & M_LOAD_FLAG;
204   }
205   bool isStore(MachineOpCode Opcode) const {
206     return get(Opcode).Flags & M_STORE_FLAG;
207   }
208
209   /// hasDelaySlot - Returns true if the specified instruction has a delay slot
210   /// which must be filled by the code generator.
211   bool hasDelaySlot(unsigned Opcode) const {
212     return get(Opcode).Flags & M_DELAY_SLOT_FLAG;
213   }
214
215   virtual bool hasResultInterlock(MachineOpCode Opcode) const {
216     return true;
217   }
218
219   // 
220   // Latencies for individual instructions and instruction pairs
221   // 
222   virtual int minLatency(MachineOpCode Opcode) const {
223     return get(Opcode).latency;
224   }
225   
226   virtual int maxLatency(MachineOpCode Opcode) const {
227     return get(Opcode).latency;
228   }
229
230   //
231   // Which operand holds an immediate constant?  Returns -1 if none
232   // 
233   virtual int getImmedConstantPos(MachineOpCode Opcode) const {
234     return -1; // immediate position is machine specific, so say -1 == "none"
235   }
236   
237   // Check if the specified constant fits in the immediate field
238   // of this machine instruction
239   // 
240   virtual bool constantFitsInImmedField(MachineOpCode Opcode,
241                                         int64_t intValue) const;
242   
243   // Return the largest positive constant that can be held in the IMMED field
244   // of this machine instruction.
245   // isSignExtended is set to true if the value is sign-extended before use
246   // (this is true for all immediate fields in SPARC instructions).
247   // Return 0 if the instruction has no IMMED field.
248   // 
249   virtual uint64_t maxImmedConstant(MachineOpCode Opcode,
250                                     bool &isSignExtended) const {
251     isSignExtended = get(Opcode).immedIsSignExtended;
252     return get(Opcode).maxImmedConst;
253   }
254 };
255
256 } // End llvm namespace
257
258 #endif