From 44a853cc530e13b3a9aa2692680a8c4c1006af85 Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Sat, 28 Jul 2001 04:09:37 +0000 Subject: [PATCH] Added MachineInstrInfo class and moved instruction-related members there. Added several fields to MachineInstrDescriptor (and renamed it from MachineInstrInfo. Latency fields are to support scheduling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/TargetMachine.h | 119 +++++++++++++++++--- lib/CodeGen/TargetMachine/TargetMachine.cpp | 76 ++++++++++++- 2 files changed, 174 insertions(+), 21 deletions(-) diff --git a/include/llvm/CodeGen/TargetMachine.h b/include/llvm/CodeGen/TargetMachine.h index 141a484d900..9395cb1ec67 100644 --- a/include/llvm/CodeGen/TargetMachine.h +++ b/include/llvm/CodeGen/TargetMachine.h @@ -18,6 +18,7 @@ class Type; class StructType; +struct MachineInstrDescriptor; //--------------------------------------------------------------------------- @@ -28,22 +29,100 @@ typedef int MachineOpCode; typedef int OpCodeMask; +// Global variable holding an array of descriptors for machine instructions. +// The actual object needs to be created separately for each target machine. +// This variable is initialized and reset by class MachineInstrInfo. +// +extern const MachineInstrDescriptor* TargetInstrDescriptors; + + +//--------------------------------------------------------------------------- // struct MachineInstrInfo: // Predefined information about each machine instruction. +// Designed to initialized statically. // -struct MachineInstrInfo { +// class MachineInstructionInfo +// Interface to description of machine instructions +// +//--------------------------------------------------------------------------- + + +const unsigned int M_NOP_FLAG = 1; +const unsigned int M_BRANCH_FLAG = 1 << 1; +const unsigned int M_CALL_FLAG = 1 << 2; +const unsigned int M_RET_FLAG = 1 << 3; +const unsigned int M_ARITH_FLAG = 1 << 4; +const unsigned int M_CC_FLAG = 1 << 6; +const unsigned int M_LOGICAL_FLAG = 1 << 6; +const unsigned int M_INT_FLAG = 1 << 7; +const unsigned int M_FLOAT_FLAG = 1 << 8; +const unsigned int M_CONDL_FLAG = 1 << 9; +const unsigned int M_LOAD_FLAG = 1 << 10; +const unsigned int M_PREFETCH_FLAG = 1 << 11; +const unsigned int M_STORE_FLAG = 1 << 12; + + +struct MachineInstrDescriptor { string opCodeString; // Assembly language mnemonic for the opcode. unsigned int numOperands; // Number of arguments for the instruction. int resultPos; // Position of the result; -1 if no result unsigned int maxImmedConst; // Largest +ve constant in IMMMED field or 0. - bool immedIsSignExtended; // Is the IMMED field sign-extended? If so, + bool immedIsSignExtended; // Is IMMED field sign-extended? If so, // smallest -ve value is -(maxImmedConst+1). + unsigned int numDelaySlots; // Number of delay slots after instruction + unsigned int latency; // Latency in machine cycles + unsigned int iclass; // Flags identifying instruction class +}; + + +class MachineInstrInfo : public NonCopyableV { +protected: + const MachineInstrDescriptor* desc; // raw array to allow static init'n + unsigned int descSize; // number of entries in the array + +public: + /*ctor*/ MachineInstrInfo(const MachineInstrDescriptor* _desc, + unsigned int _descSize); + /*dtor*/ virtual ~MachineInstrInfo(); + + const MachineInstrDescriptor& getDescriptor (MachineOpCode opCode) const { + assert(opCode < (int) descSize); + return desc[opCode]; } + virtual bool isBranch (MachineOpCode opCode) const { + return desc[opCode].iclass & M_BRANCH_FLAG;} + + virtual bool isLoad (MachineOpCode opCode) const { + return desc[opCode].iclass & M_LOAD_FLAG + || desc[opCode].iclass & M_PREFETCH_FLAG;} + + virtual bool isStore (MachineOpCode opCode) const { + return desc[opCode].iclass & M_STORE_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 desc[opCode].latency; } + + virtual int maxLatency (MachineOpCode opCode) const { + return desc[opCode].latency; } // Check if the specified constant fits in the immediate field // of this machine instruction // - bool constantFitsInImmedField (int64_t intValue) const; + virtual bool constantFitsInImmedField(MachineOpCode opCode, + int64_t intValue) const; // Return the largest +ve constant that can be held in the IMMMED field // of this machine instruction. @@ -51,22 +130,18 @@ struct MachineInstrInfo { // (this is true for all immediate fields in SPARC instructions). // Return 0 if the instruction has no IMMED field. // - inline uint64_t maxImmedConstant(bool& isSignExtended) const { - isSignExtended = immedIsSignExtended; - return maxImmedConst; } + virtual uint64_t maxImmedConstant(MachineOpCode opCode, + bool& isSignExtended) const { + isSignExtended = desc[opCode].immedIsSignExtended; + return desc[opCode].maxImmedConst; } }; -// Global variable holding an array of the above structures. -// This needs to be defined separately for each target machine. -// -extern const MachineInstrInfo* TargetMachineInstrInfo; - //--------------------------------------------------------------------------- // class TargetMachine // // Purpose: -// Machine description. +// Primary interface to machine description for the target machine. // //--------------------------------------------------------------------------- @@ -82,21 +157,31 @@ public: int minMemOpWordSize; int maxAtomicMemOpWordSize; - // Description of machine instructions (array indexed by machine opcode) - const MachineInstrInfo* machineInstrInfo; - // Register information. This needs to be reorganized into a single class. int zeroRegNum; // register that gives 0 if any (-1 if none) public: - /*ctor*/ TargetMachine () {} - /*dtor*/ virtual ~TargetMachine () {} + /*ctor*/ TargetMachine (MachineInstrInfo* mii) + : machineInstrInfo(mii) {} + /*dtor*/ virtual ~TargetMachine () {} + + const MachineInstrInfo& getInstrInfo () const { return *machineInstrInfo; } virtual unsigned int findOptimalStorageSize (const Type* ty) const; virtual unsigned int* findOptimalMemberOffsets(const StructType* stype)const; + + +protected: + // Description of machine instructions + // Protect so that subclass can control alloc/dealloc + MachineInstrInfo* machineInstrInfo; + +private: + /*ctor*/ TargetMachine (); // disable }; + //**************************************************************************/ #endif diff --git a/lib/CodeGen/TargetMachine/TargetMachine.cpp b/lib/CodeGen/TargetMachine/TargetMachine.cpp index 653f0217cd8..03819099bf2 100644 --- a/lib/CodeGen/TargetMachine/TargetMachine.cpp +++ b/lib/CodeGen/TargetMachine/TargetMachine.cpp @@ -15,18 +15,36 @@ #include "llvm/CodeGen/TargetMachine.h" #include "llvm/DerivedTypes.h" +//************************ Exported Constants ******************************/ + + +// External object describing the machine instructions +// Initialized only when the TargetMachine class is created +// and reset when that class is destroyed. +// +const MachineInstrDescriptor* TargetInstrDescriptors = NULL; + //************************ Class Implementations **************************/ //--------------------------------------------------------------------------- -// function TargetMachine::findOptimalMemberOffsets +// class TargetMachine // // Purpose: -// Compute optimal offsets for the members of a structure. -// Returns a vector of unsigned ints, one per member. -// Caller is responsible for freeing the vector. +// Machine description. +// //--------------------------------------------------------------------------- + +// function TargetMachine::findOptimalStorageSize +// +// Purpose: +// Compute optimal storage size for a structure, based on +// the optimal member offsets. +// This default implementation assumes that all sub-word data items use +// space equal to optSizeForSubWordData, and all other primitive data +// items use space according to the type. +// unsigned int TargetMachine::findOptimalStorageSize(const Type* ty) const { @@ -87,6 +105,14 @@ TargetMachine::findOptimalStorageSize(const Type* ty) const } } + +// function TargetMachine::findOptimalMemberOffsets +// +// Purpose: +// Compute optimal offsets for the members of a structure. +// Returns a vector of unsigned ints, one per member. +// Caller is responsible for freeing the vector. + unsigned int* TargetMachine::findOptimalMemberOffsets(const StructType* stype) const { @@ -102,4 +128,46 @@ TargetMachine::findOptimalMemberOffsets(const StructType* stype) const return offsetVec; } + +//--------------------------------------------------------------------------- +// class MachineInstructionInfo +// Interface to description of machine instructions +//--------------------------------------------------------------------------- + + +/*ctor*/ +MachineInstrInfo::MachineInstrInfo(const MachineInstrDescriptor* _desc, + unsigned int _descSize) + : desc(_desc), descSize(_descSize) +{ + assert(TargetInstrDescriptors == NULL && desc != NULL); + TargetInstrDescriptors = desc; // initialize global variable +} + + +/*dtor*/ +MachineInstrInfo::~MachineInstrInfo() +{ + TargetInstrDescriptors = NULL; // reset global variable +} + + +bool +MachineInstrInfo::constantFitsInImmedField(MachineOpCode opCode, + int64_t intValue) const +{ + // First, check if opCode has an immed field. + bool isSignExtended; + uint64_t maxImmedValue = this->maxImmedConstant(opCode, isSignExtended); + if (maxImmedValue != 0) + { + // Now check if the constant fits + if (intValue <= (int64_t) maxImmedValue && + intValue >= -((int64_t) maxImmedValue+1)) + return true; + } + + return false; +} + //--------------------------------------------------------------------------- -- 2.34.1