1 //===-- llvm/Target/InstrInfo.h - Target Instruction Information --*-C++-*-==//
3 // This file describes the target machine instructions to the code generator.
5 //===---------------------------------------------------------------------===//
7 #ifndef LLVM_TARGET_MACHINEINSTRINFO_H
8 #define LLVM_TARGET_MACHINEINSTRINFO_H
10 #include "Support/NonCopyable.h"
11 #include "Support/DataTypes.h"
12 #include "llvm/Constant.h"
13 #include "llvm/DerivedTypes.h"
17 class MachineInstrDescriptor;
24 class MachineCodeForInstruction;
26 //---------------------------------------------------------------------------
27 // Data types used to define information about a single machine instruction
28 //---------------------------------------------------------------------------
30 typedef int MachineOpCode;
31 typedef int OpCodeMask;
32 typedef int InstrSchedClass;
34 const MachineOpCode INVALID_MACHINE_OPCODE = -1;
37 // Global variable holding an array of descriptors for machine instructions.
38 // The actual object needs to be created separately for each target machine.
39 // This variable is initialized and reset by class MachineInstrInfo.
41 // FIXME: This should be a property of the target so that more than one target
42 // at a time can be active...
44 extern const MachineInstrDescriptor *TargetInstrDescriptors;
47 //---------------------------------------------------------------------------
48 // struct MachineInstrDescriptor:
49 // Predefined information about each machine instruction.
50 // Designed to initialized statically.
52 // class MachineInstructionInfo
53 // Interface to description of machine instructions
55 //---------------------------------------------------------------------------
58 const unsigned int M_NOP_FLAG = 1;
59 const unsigned int M_BRANCH_FLAG = 1 << 1;
60 const unsigned int M_CALL_FLAG = 1 << 2;
61 const unsigned int M_RET_FLAG = 1 << 3;
62 const unsigned int M_ARITH_FLAG = 1 << 4;
63 const unsigned int M_CC_FLAG = 1 << 6;
64 const unsigned int M_LOGICAL_FLAG = 1 << 6;
65 const unsigned int M_INT_FLAG = 1 << 7;
66 const unsigned int M_FLOAT_FLAG = 1 << 8;
67 const unsigned int M_CONDL_FLAG = 1 << 9;
68 const unsigned int M_LOAD_FLAG = 1 << 10;
69 const unsigned int M_PREFETCH_FLAG = 1 << 11;
70 const unsigned int M_STORE_FLAG = 1 << 12;
71 const unsigned int M_DUMMY_PHI_FLAG = 1 << 13;
72 const unsigned int M_PSEUDO_FLAG = 1 << 14;
75 struct MachineInstrDescriptor {
76 std::string opCodeString; // Assembly language mnemonic for the opcode.
77 int numOperands; // Number of args; -1 if variable #args
78 int resultPos; // Position of the result; -1 if no result
79 unsigned int maxImmedConst; // Largest +ve constant in IMMMED field or 0.
80 bool immedIsSignExtended; // Is IMMED field sign-extended? If so,
81 // smallest -ve value is -(maxImmedConst+1).
82 unsigned int numDelaySlots; // Number of delay slots after instruction
83 unsigned int latency; // Latency in machine cycles
84 InstrSchedClass schedClass; // enum identifying instr sched class
85 unsigned int iclass; // flags identifying machine instr class
89 class MachineInstrInfo : public NonCopyableV {
91 const TargetMachine& target;
94 const MachineInstrDescriptor* desc; // raw array to allow static init'n
95 unsigned int descSize; // number of entries in the desc array
96 unsigned int numRealOpCodes; // number of non-dummy op codes
99 MachineInstrInfo(const TargetMachine& tgt,
100 const MachineInstrDescriptor *desc, unsigned descSize,
101 unsigned numRealOpCodes);
102 virtual ~MachineInstrInfo();
104 unsigned getNumRealOpCodes() const { return numRealOpCodes; }
105 unsigned getNumTotalOpCodes() const { return descSize; }
107 const MachineInstrDescriptor& getDescriptor(MachineOpCode opCode) const {
108 assert(opCode >= 0 && opCode < (int)descSize);
112 int getNumOperands(MachineOpCode opCode) const {
113 return getDescriptor(opCode).numOperands;
116 int getResultPos(MachineOpCode opCode) const {
117 return getDescriptor(opCode).resultPos;
120 unsigned getNumDelaySlots(MachineOpCode opCode) const {
121 return getDescriptor(opCode).numDelaySlots;
124 InstrSchedClass getSchedClass(MachineOpCode opCode) const {
125 return getDescriptor(opCode).schedClass;
129 // Query instruction class flags according to the machine-independent
130 // flags listed above.
132 unsigned int getIClass(MachineOpCode opCode) const {
133 return getDescriptor(opCode).iclass;
135 bool isNop(MachineOpCode opCode) const {
136 return getDescriptor(opCode).iclass & M_NOP_FLAG;
138 bool isBranch(MachineOpCode opCode) const {
139 return getDescriptor(opCode).iclass & M_BRANCH_FLAG;
141 bool isCall(MachineOpCode opCode) const {
142 return getDescriptor(opCode).iclass & M_CALL_FLAG;
144 bool isReturn(MachineOpCode opCode) const {
145 return getDescriptor(opCode).iclass & M_RET_FLAG;
147 bool isControlFlow(MachineOpCode opCode) const {
148 return getDescriptor(opCode).iclass & M_BRANCH_FLAG
149 || getDescriptor(opCode).iclass & M_CALL_FLAG
150 || getDescriptor(opCode).iclass & M_RET_FLAG;
152 bool isArith(MachineOpCode opCode) const {
153 return getDescriptor(opCode).iclass & M_RET_FLAG;
155 bool isCCInstr(MachineOpCode opCode) const {
156 return getDescriptor(opCode).iclass & M_CC_FLAG;
158 bool isLogical(MachineOpCode opCode) const {
159 return getDescriptor(opCode).iclass & M_LOGICAL_FLAG;
161 bool isIntInstr(MachineOpCode opCode) const {
162 return getDescriptor(opCode).iclass & M_INT_FLAG;
164 bool isFloatInstr(MachineOpCode opCode) const {
165 return getDescriptor(opCode).iclass & M_FLOAT_FLAG;
167 bool isConditional(MachineOpCode opCode) const {
168 return getDescriptor(opCode).iclass & M_CONDL_FLAG;
170 bool isLoad(MachineOpCode opCode) const {
171 return getDescriptor(opCode).iclass & M_LOAD_FLAG;
173 bool isPrefetch(MachineOpCode opCode) const {
174 return getDescriptor(opCode).iclass & M_PREFETCH_FLAG;
176 bool isLoadOrPrefetch(MachineOpCode opCode) const {
177 return getDescriptor(opCode).iclass & M_LOAD_FLAG
178 || getDescriptor(opCode).iclass & M_PREFETCH_FLAG;
180 bool isStore(MachineOpCode opCode) const {
181 return getDescriptor(opCode).iclass & M_STORE_FLAG;
183 bool isMemoryAccess(MachineOpCode opCode) const {
184 return getDescriptor(opCode).iclass & M_LOAD_FLAG
185 || getDescriptor(opCode).iclass & M_PREFETCH_FLAG
186 || getDescriptor(opCode).iclass & M_STORE_FLAG;
188 bool isDummyPhiInstr(const MachineOpCode opCode) const {
189 return getDescriptor(opCode).iclass & M_DUMMY_PHI_FLAG;
191 bool isPseudoInstr(const MachineOpCode opCode) const {
192 return getDescriptor(opCode).iclass & M_PSEUDO_FLAG;
195 // Check if an instruction can be issued before its operands are ready,
196 // or if a subsequent instruction that uses its result can be issued
197 // before the results are ready.
198 // Default to true since most instructions on many architectures allow this.
200 virtual bool hasOperandInterlock(MachineOpCode opCode) const {
204 virtual bool hasResultInterlock(MachineOpCode opCode) const {
209 // Latencies for individual instructions and instruction pairs
211 virtual int minLatency(MachineOpCode opCode) const {
212 return getDescriptor(opCode).latency;
215 virtual int maxLatency(MachineOpCode opCode) const {
216 return getDescriptor(opCode).latency;
220 // Which operand holds an immediate constant? Returns -1 if none
222 virtual int getImmedConstantPos(MachineOpCode opCode) const {
223 return -1; // immediate position is machine specific, so say -1 == "none"
226 // Check if the specified constant fits in the immediate field
227 // of this machine instruction
229 virtual bool constantFitsInImmedField(MachineOpCode opCode,
230 int64_t intValue) const;
232 // Return the largest +ve constant that can be held in the IMMMED field
233 // of this machine instruction.
234 // isSignExtended is set to true if the value is sign-extended before use
235 // (this is true for all immediate fields in SPARC instructions).
236 // Return 0 if the instruction has no IMMED field.
238 virtual uint64_t maxImmedConstant(MachineOpCode opCode,
239 bool &isSignExtended) const {
240 isSignExtended = getDescriptor(opCode).immedIsSignExtended;
241 return getDescriptor(opCode).maxImmedConst;
244 //-------------------------------------------------------------------------
245 // Queries about representation of LLVM quantities (e.g., constants)
246 //-------------------------------------------------------------------------
248 // Test if this type of constant must be loaded from memory into
249 // a register, i.e., cannot be set bitwise in register and cannot
250 // use immediate fields of instructions. Note that this only makes
251 // sense for primitive types.
252 virtual bool ConstantTypeMustBeLoaded(const Constant* CV) const {
253 assert(CV->getType()->isPrimitiveType() || isa<PointerType>(CV->getType()));
254 return !(CV->getType()->isIntegral() || isa<PointerType>(CV->getType()));
257 // Test if this constant may not fit in the immediate field of the
258 // machine instructions (probably) generated for this instruction.
260 virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
261 const Instruction* I) const {
262 return true; // safe but very conservative
265 //-------------------------------------------------------------------------
266 // Code generation support for creating individual machine instructions
267 //-------------------------------------------------------------------------
269 // Get certain common op codes for the current target. this and all the
270 // Create* methods below should be moved to a machine code generation class
272 virtual MachineOpCode getNOPOpCode() const = 0;
274 // Create an instruction sequence to put the constant `val' into
275 // the virtual register `dest'. `val' may be a Constant or a
276 // GlobalValue, viz., the constant address of a global variable or function.
277 // The generated instructions are returned in `mvec'.
278 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
279 // Symbolic constants or constants that must be accessed from memory
280 // are added to the constant pool via MachineCodeForMethod::get(F).
282 virtual void CreateCodeToLoadConst(const TargetMachine& target,
286 std::vector<MachineInstr*>& mvec,
287 MachineCodeForInstruction& mcfi) const=0;
289 // Create an instruction sequence to copy an integer value `val'
290 // to a floating point value `dest' by copying to memory and back.
291 // val must be an integral type. dest must be a Float or Double.
292 // The generated instructions are returned in `mvec'.
293 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
294 // Any stack space required is allocated via mcff.
296 virtual void CreateCodeToCopyIntToFloat(const TargetMachine& target,
300 std::vector<MachineInstr*>& mvec,
301 MachineCodeForInstruction& mcfi)const=0;
303 // Similarly, create an instruction sequence to copy an FP value
304 // `val' to an integer value `dest' by copying to memory and back.
305 // The generated instructions are returned in `mvec'.
306 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
307 // Any stack space required is allocated via mcff.
309 virtual void CreateCodeToCopyFloatToInt(const TargetMachine& target,
313 std::vector<MachineInstr*>& mvec,
314 MachineCodeForInstruction& mcfi)const=0;
316 // Create instruction(s) to copy src to dest, for arbitrary types
317 // The generated instructions are returned in `mvec'.
318 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
319 // Any stack space required is allocated via mcff.
321 virtual void CreateCopyInstructionsByType(const TargetMachine& target,
325 std::vector<MachineInstr*>& mvec,
326 MachineCodeForInstruction& mcfi)const=0;
328 // Create instruction sequence to produce a sign-extended register value
329 // from an arbitrary sized value (sized in bits, not bytes).
330 // The generated instructions are appended to `mvec'.
331 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
332 // Any stack space required is allocated via mcff.
334 virtual void CreateSignExtensionInstructions(const TargetMachine& target,
337 unsigned int srcSizeInBits,
339 std::vector<MachineInstr*>& mvec,
340 MachineCodeForInstruction& mcfi) const=0;
342 // Create instruction sequence to produce a zero-extended register value
343 // from an arbitrary sized value (sized in bits, not bytes).
344 // The generated instructions are appended to `mvec'.
345 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
346 // Any stack space required is allocated via mcff.
348 virtual void CreateZeroExtensionInstructions(const TargetMachine& target,
351 unsigned int srcSizeInBits,
353 std::vector<MachineInstr*>& mvec,
354 MachineCodeForInstruction& mcfi) const=0;