class Type;
class StructType;
+struct MachineInstrDescriptor;
//---------------------------------------------------------------------------
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.
// (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.
//
//---------------------------------------------------------------------------
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
#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
{
}
}
+
+// 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
{
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;
+}
+
//---------------------------------------------------------------------------