llvm bug #1350, parts 1, 2, and 3.
authorNate Begeman <natebegeman@mac.com>
Tue, 1 May 2007 05:57:02 +0000 (05:57 +0000)
committerNate Begeman <natebegeman@mac.com>
Tue, 1 May 2007 05:57:02 +0000 (05:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36618 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineInstr.h
include/llvm/Target/MRegisterInfo.h
lib/CodeGen/MachineInstr.cpp
lib/Target/PowerPC/PPCRegisterInfo.td
lib/Target/Target.td
utils/TableGen/RegisterInfoEmitter.cpp

index a81c70e37119078fa339bcf1a47a9239bca7fa12..a6e14e21fdfe5bef84905c41e3f26c38d5d43dab 100644 (file)
@@ -71,10 +71,17 @@ private:
                                // immediately after the write. i.e. A register
                                // that is defined but never used.
   
-  /// offset - Offset to address of global or external, only valid for
-  /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
-  int offset;
-
+  /// auxInfo - auxiliary information used by the MachineOperand
+  union {
+    /// offset - Offset to address of global or external, only valid for
+    /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
+    int offset;
+
+    /// subReg - SubRegister number, only valid for MO_Register.  A value of 0
+    /// indicates the MO_Register has no subReg.
+    unsigned subReg;
+  } auxInfo;
+  
   MachineOperand() {}
 
   void print(std::ostream &os) const;
@@ -95,7 +102,7 @@ public:
     Op.IsImp = false;
     Op.IsKill = false;
     Op.IsDead = false;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
     return Op;
   }
   
@@ -106,7 +113,7 @@ public:
     IsKill   = MO.IsKill;
     IsDead   = MO.IsDead;
     opType   = MO.opType;
-    offset   = MO.offset;
+    auxInfo  = MO.auxInfo;
     return *this;
   }
 
@@ -169,7 +176,11 @@ public:
   int getOffset() const {
     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
         "Wrong MachineOperand accessor");
-    return offset;
+    return auxInfo.offset;
+  }
+  unsigned getSubReg() const {
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    return auxInfo.subReg;
   }
   const char *getSymbolName() const {
     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
@@ -254,7 +265,11 @@ public:
     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
             isJumpTableIndex()) &&
         "Wrong MachineOperand accessor");
-    offset = Offset;
+    auxInfo.offset = Offset;
+  }
+  void setSubReg(unsigned subReg) {
+    assert(isRegister() && "Wrong MachineOperand accessor");
+    auxInfo.subReg = subReg;
   }
   void setConstantPoolIndex(unsigned Idx) {
     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
@@ -433,7 +448,7 @@ public:
     Op.IsKill = IsKill;
     Op.IsDead = IsDead;
     Op.contents.RegNo = Reg;
-    Op.offset = 0;
+    Op.auxInfo.subReg = 0;
   }
 
   /// addImmOperand - Add a zero extended constant argument to the
@@ -443,14 +458,14 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_Immediate;
     Op.contents.immedVal = Val;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
 
   void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_MachineBasicBlock;
     Op.contents.MBB = MBB;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
 
   /// addFrameIndexOperand - Add an abstract frame index to the instruction
@@ -459,7 +474,7 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_FrameIndex;
     Op.contents.immedVal = Idx;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
 
   /// addConstantPoolndexOperand - Add a constant pool object index to the
@@ -469,7 +484,7 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_ConstantPoolIndex;
     Op.contents.immedVal = Idx;
-    Op.offset = Offset;
+    Op.auxInfo.offset = Offset;
   }
 
   /// addJumpTableIndexOperand - Add a jump table object index to the
@@ -479,14 +494,14 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_JumpTableIndex;
     Op.contents.immedVal = Idx;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
   
   void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_GlobalAddress;
     Op.contents.GV = GV;
-    Op.offset = Offset;
+    Op.auxInfo.offset = Offset;
   }
 
   /// addExternalSymbolOperand - Add an external symbol operand to this instr
@@ -495,7 +510,7 @@ public:
     MachineOperand &Op = AddNewOperand();
     Op.opType = MachineOperand::MO_ExternalSymbol;
     Op.contents.SymbolName = SymName;
-    Op.offset = 0;
+    Op.auxInfo.offset = 0;
   }
 
   //===--------------------------------------------------------------------===//
index 4b9389accb72d07c582578c150cbe86f7b91a942..da4b750fe1ecff47ffaca39e4493dac19412908a 100644 (file)
@@ -41,7 +41,7 @@ class Type;
 /// The SubRegs field is a zero terminated array of registers that are
 /// sub-registers of the specific register, e.g. AL, AH are sub-registers of AX.
 /// The SuperRegs field is a zero terminated array of registers that are
-/// super-registers of the specific register, e.g. RAX, EAX, are sub-registers
+/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
 /// of AX.
 ///
 struct TargetRegisterDesc {
@@ -354,6 +354,10 @@ public:
   /// register scavenger to determine what registers are free.
   virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
 
+  /// getSubReg - Returns the physical register number of sub-register "Index"
+  /// for physical register RegNo.
+  virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
+
   //===--------------------------------------------------------------------===//
   // Register Class Information
   //
index 1c0d9cc4eb1c195d1efb270f2d6e6f5352d0b9d0..9d09a9f95e54b11d3e89e2d694a4d1c7ce7138be 100644 (file)
@@ -39,7 +39,7 @@ void MachineInstr::addImplicitDefUseOperands() {
       Op.IsKill = false;
       Op.IsDead = false;
       Op.contents.RegNo = *ImpDefs;
-      Op.offset = 0;
+      Op.auxInfo.subReg = 0;
       Operands.push_back(Op);
     }
   if (TID->ImplicitUses)
@@ -51,7 +51,7 @@ void MachineInstr::addImplicitDefUseOperands() {
       Op.IsKill = false;
       Op.IsDead = false;
       Op.contents.RegNo = *ImpUses;
-      Op.offset = 0;
+      Op.auxInfo.subReg = 0;
       Operands.push_back(Op);
     }
 }
index b1040e9204501d79820b83c338aedb8522c85569..3891755247ef77d0a9a30daf8e32ffb031579b05 100644 (file)
@@ -43,10 +43,16 @@ class VR<bits<5> num, string n> : PPCReg<n> {
 }
 
 // CR - One of the 8 4-bit condition registers
-class CR<bits<5> num, string n> : PPCReg<n> {
+class CR<bits<3> num, string n> : PPCReg<n> {
+  field bits<3> Num = num;
+}
+
+// CRBIT - One of the 32 1-bit condition register fields
+class CRBIT<bits<5> num, string n> : PPCReg<n> {
   field bits<5> Num = num;
 }
 
+
 // General-purpose registers
 def R0  : GPR< 0,  "r0">, DwarfRegNum<0>;
 def R1  : GPR< 1,  "r1">, DwarfRegNum<1>;
@@ -193,6 +199,49 @@ def CR5 : CR<5, "cr5">, DwarfRegNum<73>;
 def CR6 : CR<6, "cr6">, DwarfRegNum<74>;
 def CR7 : CR<7, "cr7">, DwarfRegNum<75>;
 
+// Condition register bits
+def CR0LT : CRBIT< 0, "0">, DwarfRegNum<0>;
+def CR0GT : CRBIT< 1, "1">, DwarfRegNum<0>;
+def CR0EQ : CRBIT< 2, "2">, DwarfRegNum<0>;
+def CR0UN : CRBIT< 3, "3">, DwarfRegNum<0>;
+def CR1LT : CRBIT< 4, "4">, DwarfRegNum<0>;
+def CR1GT : CRBIT< 5, "5">, DwarfRegNum<0>;
+def CR1EQ : CRBIT< 6, "6">, DwarfRegNum<0>;
+def CR1UN : CRBIT< 7, "7">, DwarfRegNum<0>;
+def CR2LT : CRBIT< 8, "8">, DwarfRegNum<0>;
+def CR2GT : CRBIT< 9, "9">, DwarfRegNum<0>;
+def CR2EQ : CRBIT<10, "10">, DwarfRegNum<0>;
+def CR2UN : CRBIT<11, "11">, DwarfRegNum<0>;
+def CR3LT : CRBIT<12, "12">, DwarfRegNum<0>;
+def CR3GT : CRBIT<13, "13">, DwarfRegNum<0>;
+def CR3EQ : CRBIT<14, "14">, DwarfRegNum<0>;
+def CR3UN : CRBIT<15, "15">, DwarfRegNum<0>;
+def CR4LT : CRBIT<16, "16">, DwarfRegNum<0>;
+def CR4GT : CRBIT<17, "17">, DwarfRegNum<0>;
+def CR4EQ : CRBIT<18, "18">, DwarfRegNum<0>;
+def CR4UN : CRBIT<19, "19">, DwarfRegNum<0>;
+def CR5LT : CRBIT<20, "20">, DwarfRegNum<0>;
+def CR5GT : CRBIT<21, "21">, DwarfRegNum<0>;
+def CR5EQ : CRBIT<22, "22">, DwarfRegNum<0>;
+def CR5UN : CRBIT<23, "23">, DwarfRegNum<0>;
+def CR6LT : CRBIT<24, "24">, DwarfRegNum<0>;
+def CR6GT : CRBIT<25, "25">, DwarfRegNum<0>;
+def CR6EQ : CRBIT<26, "26">, DwarfRegNum<0>;
+def CR6UN : CRBIT<27, "27">, DwarfRegNum<0>;
+def CR7LT : CRBIT<28, "28">, DwarfRegNum<0>;
+def CR7GT : CRBIT<29, "29">, DwarfRegNum<0>;
+def CR7EQ : CRBIT<30, "30">, DwarfRegNum<0>;
+def CR7UN : CRBIT<31, "31">, DwarfRegNum<0>;
+
+def : SubRegSet<1, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
+                   [CR0LT, CR1LT, CR2LT, CR3LT, CR4LT, CR5LT, CR6LT, CR7LT]>;
+def : SubRegSet<2, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
+                   [CR0GT, CR1GT, CR2GT, CR3GT, CR4GT, CR5GT, CR6GT, CR7GT]>;
+def : SubRegSet<3, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
+                   [CR0EQ, CR1EQ, CR2EQ, CR3EQ, CR4EQ, CR5EQ, CR6EQ, CR7EQ]>;
+def : SubRegSet<4, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
+                   [CR0UN, CR1UN, CR2UN, CR3UN, CR4UN, CR5UN, CR6UN, CR7UN]>;
+
 // Link register
 def LR  : SPR<8, "lr">, DwarfRegNum<65>;
 //let Aliases = [LR] in
index 094a4adf3ba38196aec44ec585df0300f11b0c15..fce45a5c2d4e2fe803fabea8b1649a38377a8edc 100644 (file)
@@ -67,13 +67,15 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
   let SubRegs = subregs;
 }
 
-// RegisterGroup - This can be used to define instances of Register which
-// need to specify aliases.
-// List "aliases" specifies which registers are aliased to this one.  This
-// allows the code generator to be careful not to put two values with 
-// overlapping live ranges into registers which alias.
-class RegisterGroup<string n, list<Register> aliases> : Register<n> {
-  let Aliases = aliases;
+// SubRegSet - This can be used to define a specific mapping of registers to
+// indices, for use as named subregs of a particular physical register.  Each
+// register in 'subregs' becomes an addressable subregister at index 'n' of the
+// corresponding register in 'regs'.
+class SubRegSet<int n, list<Register> regs, list<Register> subregs> {
+  int index = n;
+  
+  list<Register> From = regs;
+  list<Register> To = subregs;
 }
 
 // RegisterClass - Now that all of the registers are defined, and aliases
index d4671a5fbbbf45fd9dfe825c300d4685e6858e4e..61d731ad73fd2d598402648d804c4a9c6b501826 100644 (file)
@@ -61,6 +61,7 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) {
      << "  " << ClassName
      << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
      << "  int getDwarfRegNum(unsigned RegNum) const;\n"
+     << "  unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
      << "};\n\n";
 
   const std::vector<CodeGenRegisterClass> &RegisterClasses =
@@ -322,6 +323,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
   std::map<Record*, std::set<Record*> > RegisterSubRegs;
   std::map<Record*, std::set<Record*> > RegisterSuperRegs;
   std::map<Record*, std::set<Record*> > RegisterAliases;
+  std::map<Record*, std::vector<std::pair<int, Record*> > > SubRegVectors;
   const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
 
   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
@@ -441,6 +443,40 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
 
   std::string ClassName = Target.getName() + "GenRegisterInfo";
 
+  // Calculate the mapping of subregister+index pairs to physical registers.
+  std::vector<Record*> SubRegs = Records.getAllDerivedDefinitions("SubRegSet");
+  for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
+    int subRegIndex = SubRegs[i]->getValueAsInt("index");
+    std::vector<Record*> From = SubRegs[i]->getValueAsListOfDefs("From");
+    std::vector<Record*> To   = SubRegs[i]->getValueAsListOfDefs("To");
+    
+    assert((From.size() == To.size()) && 
+           "SubRegSet has mismatched from/to size");
+    
+    // For each entry in from/to vectors, insert the to register at index 
+    for (unsigned ii = 0, ee = From.size(); ii != ee; ++ii)
+      SubRegVectors[From[ii]].push_back(std::make_pair(subRegIndex, To[ii]));
+  }
+  
+  // Emit the subregister + index mapping function based on the information
+  // calculated above.
+  OS << "unsigned " << ClassName 
+     << "::getSubReg(unsigned RegNo, unsigned Index) const {\n"
+     << "  switch (RegNo) {\n"
+     << "  default: abort(); break;\n";
+  for (std::map<Record*, std::vector<std::pair<int, Record*> > >::iterator 
+        I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) {
+    OS << "  case " << getQualifiedName(I->first) << ":\n";
+    OS << "    switch (Index) {\n";
+    OS << "    default: abort(); break;\n";
+    for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+      OS << "    case " << (I->second)[i].first << ": return "
+         << getQualifiedName((I->second)[i].second) << ";\n";
+    OS << "    }; break;\n";
+  }
+  OS << "  };\n";
+  OS << "}\n\n";
+  
   // Emit the constructor of the class...
   OS << ClassName << "::" << ClassName
      << "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n"