llvm-6502/include/llvm/Target/TargetInstrInfo.h

382 lines
14 KiB
C
Raw Normal View History

//===-- llvm/Target/TargetInstrInfo.h - Instruction Info --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the target machine instructions to the code generator.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_TARGETINSTRINFO_H
#define LLVM_TARGET_TARGETINSTRINFO_H
#include "Support/DataTypes.h"
#include <vector>
#include <cassert>
namespace llvm {
class MachineInstr;
class TargetMachine;
class Value;
class Type;
class Instruction;
class Constant;
class Function;
class MachineCodeForInstruction;
//---------------------------------------------------------------------------
// Data types used to define information about a single machine instruction
//---------------------------------------------------------------------------
typedef short MachineOpCode;
typedef unsigned InstrSchedClass;
//---------------------------------------------------------------------------
// struct TargetInstrDescriptor:
// Predefined information about each machine instruction.
// Designed to initialized statically.
//
const unsigned M_NOP_FLAG = 1 << 0;
const unsigned M_BRANCH_FLAG = 1 << 1;
const unsigned M_CALL_FLAG = 1 << 2;
const unsigned M_RET_FLAG = 1 << 3;
const unsigned M_CC_FLAG = 1 << 6;
const unsigned M_LOAD_FLAG = 1 << 10;
const unsigned M_STORE_FLAG = 1 << 12;
const unsigned M_DUMMY_PHI_FLAG = 1 << 13;
const unsigned M_PSEUDO_FLAG = 1 << 14; // Pseudo instruction
// 3-addr instructions which really work like 2-addr ones, eg. X86 add/sub
const unsigned M_2_ADDR_FLAG = 1 << 15;
// M_TERMINATOR_FLAG - Is this instruction part of the terminator for a basic
// block? Typically this is things like return and branch instructions.
// Various passes use this to insert code into the bottom of a basic block, but
// before control flow occurs.
const unsigned M_TERMINATOR_FLAG = 1 << 16;
struct TargetInstrDescriptor {
const char * Name; // Assembly language mnemonic for the opcode.
int numOperands; // Number of args; -1 if variable #args
int resultPos; // Position of the result; -1 if no result
unsigned maxImmedConst; // Largest +ve constant in IMMED field or 0.
bool immedIsSignExtended; // Is IMMED field sign-extended? If so,
// smallest -ve value is -(maxImmedConst+1).
unsigned numDelaySlots; // Number of delay slots after instruction
unsigned latency; // Latency in machine cycles
InstrSchedClass schedClass; // enum identifying instr sched class
unsigned Flags; // flags identifying machine instr class
unsigned TSFlags; // Target Specific Flag values
const unsigned *ImplicitUses; // Registers implicitly read by this instr
const unsigned *ImplicitDefs; // Registers implicitly defined by this instr
};
//---------------------------------------------------------------------------
///
/// TargetInstrInfo - Interface to description of machine instructions
///
class TargetInstrInfo {
const TargetInstrDescriptor* desc; // raw array to allow static init'n
unsigned NumOpcodes; // number of entries in the desc array
unsigned numRealOpCodes; // number of non-dummy op codes
TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT
void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT
public:
TargetInstrInfo(const TargetInstrDescriptor *desc, unsigned NumOpcodes);
virtual ~TargetInstrInfo();
// Invariant: All instruction sets use opcode #0 as the PHI instruction
enum { PHI = 0 };
unsigned getNumOpcodes() const { return NumOpcodes; }
/// get - Return the machine instruction descriptor that corresponds to the
/// specified instruction opcode.
///
const TargetInstrDescriptor& get(MachineOpCode opCode) const {
assert((unsigned)opCode < NumOpcodes);
return desc[opCode];
}
const char *getName(MachineOpCode opCode) const {
return get(opCode).Name;
}
int getNumOperands(MachineOpCode opCode) const {
return get(opCode).numOperands;
}
InstrSchedClass getSchedClass(MachineOpCode opCode) const {
return get(opCode).schedClass;
}
Nice tasty llc fixes. These should fix LLC for x86 for everything in SingleSource except oopack and Oscar. (Sorry, Oscar.) include/llvm/Target/TargetInstrInfo.h: Remove virtual print method. Add accessors for ImplicitUses/Defs. lib/Target/TargetInstrInfo.cpp: Remove virtual print method. If you really wanted this, just use MI->print(O, TM); instead... lib/Target/X86: FloatingPoint.cpp: ...like this. X86InstrInfo.h: Remove virtual print method. Define the PrintImplUses target-specific flag bit. X86InstrInfo.def: Add the PrintImplUses flag to all the instructions which implicitly use CL, because the assembler needs to see the CL in order to generate the right instruction. Printer.cpp: Ditch fnIndex at Chris's request. Now we use CurrentFnName to name constants in the constant pool for each function instead. This avoids keeping state between runOnMachineFunction() invocations, which is a no-no. Having MangledGlobals be global is a bogon I'd like to get rid of too, but making it a static member of Printer causes link errors (why???). Make NumberForBB into a member of Printer instead of a global, too. Make printOp and printMemReference into methods of Printer. X86InstrInfo::print is now Printer::printMachineInstruction, because TargetInstrInfo::print is history. (Because of this, we have to qualify the names of some TargetInstrInfo methods we call.) Print out the ImplicitUses field of any instruction we print that has the PrintImplUses bit set. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6924 91177308-0d34-0410-b5e6-96231b3b80d8
2003-06-27 00:00:48 +00:00
const unsigned *getImplicitUses(MachineOpCode opCode) const {
return get(opCode).ImplicitUses;
}
const unsigned *getImplicitDefs(MachineOpCode opCode) const {
return get(opCode).ImplicitDefs;
}
//
// Query instruction class flags according to the machine-independent
// flags listed above.
//
bool isReturn(MachineOpCode opCode) const {
return get(opCode).Flags & M_RET_FLAG;
}
bool isPseudoInstr(MachineOpCode opCode) const {
return get(opCode).Flags & M_PSEUDO_FLAG;
}
bool isTwoAddrInstr(MachineOpCode opCode) const {
return get(opCode).Flags & M_2_ADDR_FLAG;
}
bool isTerminatorInstr(unsigned Opcode) const {
return get(Opcode).Flags & M_TERMINATOR_FLAG;
}
//
// Return true if the instruction is a register to register move and
// leave the source and dest operands in the passed parameters.
//
virtual bool isMoveInstr(const MachineInstr& MI,
unsigned& sourceReg,
unsigned& destReg) const {
return false;
}
//-------------------------------------------------------------------------
// Code generation support for creating individual machine instructions
//
// WARNING: These methods are Sparc specific
//
// DO NOT USE ANY OF THESE METHODS THEY ARE DEPRECATED!
//
//-------------------------------------------------------------------------
int getResultPos(MachineOpCode opCode) const {
return get(opCode).resultPos;
}
unsigned getNumDelaySlots(MachineOpCode opCode) const {
return get(opCode).numDelaySlots;
}
bool isCCInstr(MachineOpCode opCode) const {
return get(opCode).Flags & M_CC_FLAG;
}
bool isNop(MachineOpCode opCode) const {
return get(opCode).Flags & M_NOP_FLAG;
}
bool isBranch(MachineOpCode opCode) const {
return get(opCode).Flags & M_BRANCH_FLAG;
}
bool isCall(MachineOpCode opCode) const {
return get(opCode).Flags & M_CALL_FLAG;
}
bool isLoad(MachineOpCode opCode) const {
return get(opCode).Flags & M_LOAD_FLAG;
}
bool isStore(MachineOpCode opCode) const {
return get(opCode).Flags & M_STORE_FLAG;
}
bool isDummyPhiInstr(MachineOpCode opCode) const {
return get(opCode).Flags & M_DUMMY_PHI_FLAG;
}
// Check if an instruction can be issued before its operands are ready,
// or if a subsequent instruction that uses its result can be issued
// before the results are ready.
// Default to true since most instructions on many architectures allow this.
//
virtual bool hasOperandInterlock(MachineOpCode opCode) const {
return true;
}
virtual bool hasResultInterlock(MachineOpCode opCode) const {
return true;
}
//
// Latencies for individual instructions and instruction pairs
//
virtual int minLatency(MachineOpCode opCode) const {
return get(opCode).latency;
}
virtual int maxLatency(MachineOpCode opCode) const {
return get(opCode).latency;
}
//
// Which operand holds an immediate constant? Returns -1 if none
//
virtual int getImmedConstantPos(MachineOpCode opCode) const {
return -1; // immediate position is machine specific, so say -1 == "none"
}
// Check if the specified constant fits in the immediate field
// of this machine instruction
//
virtual bool constantFitsInImmedField(MachineOpCode opCode,
int64_t intValue) const;
// Return the largest positive constant that can be held in the IMMED field
// of this machine instruction.
// isSignExtended is set to true if the value is sign-extended before use
// (this is true for all immediate fields in SPARC instructions).
// Return 0 if the instruction has no IMMED field.
//
virtual uint64_t maxImmedConstant(MachineOpCode opCode,
bool &isSignExtended) const {
isSignExtended = get(opCode).immedIsSignExtended;
return get(opCode).maxImmedConst;
}
//-------------------------------------------------------------------------
// Queries about representation of LLVM quantities (e.g., constants)
//-------------------------------------------------------------------------
/// ConstantTypeMustBeLoaded - Test if this type of constant must be loaded
/// from memory into a register, i.e., cannot be set bitwise in register and
/// cannot use immediate fields of instructions. Note that this only makes
/// sense for primitive types.
///
virtual bool ConstantTypeMustBeLoaded(const Constant* CV) const;
// Test if this constant may not fit in the immediate field of the
// machine instructions (probably) generated for this instruction.
//
virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
const Instruction* I) const {
return true; // safe but very conservative
}
// Get certain common op codes for the current target. this and all the
// Create* methods below should be moved to a machine code generation class
//
virtual MachineOpCode getNOPOpCode() const { abort(); }
// Get the value of an integral constant in the form that must
// be put into the machine register. The specified constant is interpreted
// as (i.e., converted if necessary to) the specified destination type. The
// result is always returned as an uint64_t, since the representation of
// int64_t and uint64_t are identical. The argument can be any known const.
//
// isValidConstant is set to true if a valid constant was found.
//
virtual uint64_t ConvertConstantToIntType(const TargetMachine &target,
const Value *V,
const Type *destType,
bool &isValidConstant) const {
abort();
}
// Create an instruction sequence to put the constant `val' into
// the virtual register `dest'. `val' may be a Constant or a
// GlobalValue, viz., the constant address of a global variable or function.
// The generated instructions are returned in `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Symbolic constants or constants that must be accessed from memory
// are added to the constant pool via MachineFunction::get(F).
//
virtual void CreateCodeToLoadConst(const TargetMachine& target,
Function* F,
Value* val,
Instruction* dest,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const {
abort();
}
// Create an instruction sequence to copy an integer value `val'
// to a floating point value `dest' by copying to memory and back.
// val must be an integral type. dest must be a Float or Double.
// The generated instructions are returned in `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateCodeToCopyIntToFloat(const TargetMachine& target,
Function* F,
Value* val,
Instruction* dest,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& MI) const {
abort();
}
// Similarly, create an instruction sequence to copy an FP value
// `val' to an integer value `dest' by copying to memory and back.
// The generated instructions are returned in `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateCodeToCopyFloatToInt(const TargetMachine& target,
Function* F,
Value* val,
Instruction* dest,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& MI) const {
abort();
}
// Create instruction(s) to copy src to dest, for arbitrary types
// The generated instructions are returned in `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateCopyInstructionsByType(const TargetMachine& target,
Function* F,
Value* src,
Instruction* dest,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& MI) const {
abort();
}
// Create instruction sequence to produce a sign-extended register value
// from an arbitrary sized value (sized in bits, not bytes).
// The generated instructions are appended to `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateSignExtensionInstructions(const TargetMachine& target,
Function* F,
Value* srcVal,
Value* destVal,
unsigned numLowBits,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& MI) const {
abort();
}
// Create instruction sequence to produce a zero-extended register value
// from an arbitrary sized value (sized in bits, not bytes).
// The generated instructions are appended to `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateZeroExtensionInstructions(const TargetMachine& target,
Function* F,
Value* srcVal,
Value* destVal,
unsigned srcSizeInBits,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const {
abort();
}
};
} // End llvm namespace
#endif