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