Added MachineInstrInfo class and moved instruction-related members there.
authorVikram S. Adve <vadve@cs.uiuc.edu>
Sat, 28 Jul 2001 04:09:37 +0000 (04:09 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Sat, 28 Jul 2001 04:09:37 +0000 (04:09 +0000)
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
lib/CodeGen/TargetMachine/TargetMachine.cpp

index 141a484d9007b96842ef55ca58ac7206847631e3..9395cb1ec675035ec8be40df1e0d44a4d608408a 100644 (file)
@@ -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
index 653f0217cd8024c4302aa3ef6f0d142e3f99f435..03819099bf218810b5e4d1237f01c92cbcbdab65 100644 (file)
 #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;
+}
+
 //---------------------------------------------------------------------------