TargetInstrInfo.h revision 502374a58fcd1c28065170a8c4a210be002ff190
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 "llvm/Constant.h"
13#include "llvm/DerivedTypes.h"
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 << 0;
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_ARITH_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  // Queries about representation of LLVM quantities (e.g., constants)
244  //-------------------------------------------------------------------------
245
246  // Test if this type of constant must be loaded from memory into
247  // a register, i.e., cannot be set bitwise in register and cannot
248  // use immediate fields of instructions.  Note that this only makes
249  // sense for primitive types.
250  virtual bool ConstantTypeMustBeLoaded(const Constant* CV) const {
251    assert(CV->getType()->isPrimitiveType() || isa<PointerType>(CV->getType()));
252    return !(CV->getType()->isIntegral() || isa<PointerType>(CV->getType()));
253  }
254
255  // Test if this constant may not fit in the immediate field of the
256  // machine instructions (probably) generated for this instruction.
257  //
258  virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
259                                             const Instruction* I) const {
260    return true;                        // safe but very conservative
261  }
262
263  //-------------------------------------------------------------------------
264  // Code generation support for creating individual machine instructions
265  //-------------------------------------------------------------------------
266
267  // Get certain common op codes for the current target.  this and all the
268  // Create* methods below should be moved to a machine code generation class
269  //
270  virtual MachineOpCode getNOPOpCode() const = 0;
271
272  // Create an instruction sequence to put the constant `val' into
273  // the virtual register `dest'.  `val' may be a Constant or a
274  // GlobalValue, viz., the constant address of a global variable or function.
275  // The generated instructions are returned in `mvec'.
276  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
277  // Symbolic constants or constants that must be accessed from memory
278  // are added to the constant pool via MachineCodeForMethod::get(F).
279  //
280  virtual void  CreateCodeToLoadConst(const TargetMachine& target,
281                                      Function* F,
282                                      Value* val,
283                                      Instruction* dest,
284                                      std::vector<MachineInstr*>& mvec,
285                                      MachineCodeForInstruction& mcfi) const=0;
286
287  // Create an instruction sequence to copy an integer value `val'
288  // to a floating point value `dest' by copying to memory and back.
289  // val must be an integral type.  dest must be a Float or Double.
290  // The generated instructions are returned in `mvec'.
291  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
292  // Any stack space required is allocated via mcff.
293  //
294  virtual void  CreateCodeToCopyIntToFloat(const TargetMachine& target,
295                                       Function* F,
296                                       Value* val,
297                                       Instruction* dest,
298                                       std::vector<MachineInstr*>& mvec,
299                                       MachineCodeForInstruction& mcfi)const=0;
300
301  // Similarly, create an instruction sequence to copy an FP value
302  // `val' to an integer value `dest' by copying to memory and back.
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  CreateCodeToCopyFloatToInt(const TargetMachine& target,
308                                       Function* F,
309                                       Value* val,
310                                       Instruction* dest,
311                                       std::vector<MachineInstr*>& mvec,
312                                       MachineCodeForInstruction& mcfi)const=0;
313
314  // Create instruction(s) to copy src to dest, for arbitrary types
315  // The generated instructions are returned in `mvec'.
316  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
317  // Any stack space required is allocated via mcff.
318  //
319  virtual void CreateCopyInstructionsByType(const TargetMachine& target,
320                                       Function* F,
321                                       Value* src,
322                                       Instruction* dest,
323                                       std::vector<MachineInstr*>& mvec,
324                                       MachineCodeForInstruction& mcfi)const=0;
325
326  // Create instruction sequence to produce a sign-extended register value
327  // from an arbitrary sized value (sized in bits, not bytes).
328  // The generated instructions are appended to `mvec'.
329  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
330  // Any stack space required is allocated via mcff.
331  //
332  virtual void CreateSignExtensionInstructions(const TargetMachine& target,
333                                       Function* F,
334                                       Value* srcVal,
335                                       Value* destVal,
336                                       unsigned int numLowBits,
337                                       std::vector<MachineInstr*>& mvec,
338                                       MachineCodeForInstruction& mcfi) const=0;
339
340  // Create instruction sequence to produce a zero-extended register value
341  // from an arbitrary sized value (sized in bits, not bytes).
342  // The generated instructions are appended to `mvec'.
343  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
344  // Any stack space required is allocated via mcff.
345  //
346  virtual void CreateZeroExtensionInstructions(const TargetMachine& target,
347                                       Function* F,
348                                       Value* srcVal,
349                                       Value* destVal,
350                                       unsigned int srcSizeInBits,
351                                       std::vector<MachineInstr*>& mvec,
352                                       MachineCodeForInstruction& mcfi) const=0;
353};
354
355#endif
356