Add the SubRegIndex TableGen class.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Mon, 24 May 2010 14:48:12 +0000 (14:48 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Mon, 24 May 2010 14:48:12 +0000 (14:48 +0000)
This is the beginning of purely symbolic subregister indices, but we need a bit
of jiggling before the explicit numeric indices can be completely removed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104492 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/Target.td
lib/Target/Blackfin/BlackfinInstrInfo.td
lib/Target/Blackfin/BlackfinRegisterInfo.cpp
lib/Target/Blackfin/BlackfinRegisterInfo.h
lib/Target/Blackfin/BlackfinRegisterInfo.td
lib/Target/X86/X86InstrInfo.cpp
lib/Target/X86/X86RegisterInfo.td
utils/TableGen/CodeGenDAGPatterns.cpp
utils/TableGen/DAGISelMatcherGen.cpp
utils/TableGen/FastISelEmitter.cpp
utils/TableGen/RegisterInfoEmitter.cpp

index 607dac7bd420c2c470d61cb7d1332f600a4bffa5..94430bc6cc0dc076af553a92eab06ab5791da3d8 100644 (file)
@@ -21,6 +21,14 @@ include "llvm/Intrinsics.td"
 
 class RegisterClass; // Forward def
 
+class SubRegIndex {
+  string Namespace = "";
+
+  // This explicit numbering is going away after RegisterClass::SubRegClassList
+  // is replaced.
+  int NumberHack;
+}
+
 // Register - You should define one instance of this class for each register
 // in the target machine.  String n will become the "name" of the register.
 class Register<string n> {
index 2471688b9052bc8ceac80dcb71ede03da080f11a..5cf350a0cb4f2b1437637a248e872cfd2f5b27a9 100644 (file)
@@ -301,9 +301,9 @@ def LOAD32p_8z: F1<(outs D:$dst), (ins P:$ptr),
 
 def : Pat<(i32 (extloadi8 P:$ptr)), (LOAD32p_8z P:$ptr)>;
 def : Pat<(i16 (extloadi8 P:$ptr)),
-          (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), bfin_subreg_lo16)>;
+          (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>;
 def : Pat<(i16 (zextloadi8 P:$ptr)),
-          (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), bfin_subreg_lo16)>;
+          (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>;
 
 def LOAD32p_imm16_8z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
                          "$dst = b[$ptr + $off] (z);",
@@ -313,17 +313,17 @@ def : Pat<(i32 (extloadi8 (add P:$ptr, imm16:$off))),
           (LOAD32p_imm16_8z P:$ptr, imm:$off)>;
 def : Pat<(i16 (extloadi8 (add P:$ptr, imm16:$off))),
           (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off),
-                           bfin_subreg_lo16)>;
+                           lo16)>;
 def : Pat<(i16 (zextloadi8 (add P:$ptr, imm16:$off))),
           (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off),
-                           bfin_subreg_lo16)>;
+                           lo16)>;
 
 def LOAD32p_8s: F1<(outs D:$dst), (ins P:$ptr),
                    "$dst = b[$ptr] (x);",
                    [(set D:$dst, (sextloadi8 P:$ptr))]>;
 
 def : Pat<(i16 (sextloadi8 P:$ptr)),
-          (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), bfin_subreg_lo16)>;
+          (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), lo16)>;
 
 def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
                          "$dst = b[$ptr + $off] (x);",
@@ -331,7 +331,7 @@ def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
 
 def : Pat<(i16 (sextloadi8 (add P:$ptr, imm16:$off))),
           (EXTRACT_SUBREG (LOAD32p_imm16_8s P:$ptr, imm:$off),
-                           bfin_subreg_lo16)>;
+                           lo16)>;
 // Memory loads without patterns
 
 let mayLoad = 1 in {
@@ -468,16 +468,16 @@ def STORE32i_post: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr, M:$off),
 
 def : Pat<(truncstorei16 D:$val, PI:$ptr),
           (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)),
-                                     bfin_subreg_lo16), PI:$ptr)>;
+                                     lo16), PI:$ptr)>;
 
 def : Pat<(truncstorei16 (srl D:$val, (i16 16)), PI:$ptr),
           (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)),
-                                     bfin_subreg_hi16), PI:$ptr)>;
+                                     hi16), PI:$ptr)>;
 
 def : Pat<(truncstorei8 D16L:$val, P:$ptr),
           (STORE8p (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
                                   (i16 (COPY_TO_REGCLASS D16L:$val, D16L)),
-                                  bfin_subreg_lo16),
+                                  lo16),
                    P:$ptr)>;
 
 //===----------------------------------------------------------------------===//
@@ -516,19 +516,19 @@ def : Pat<(sext_inreg D16L:$src, i8),
           (EXTRACT_SUBREG (MOVEsext8
                            (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
                                           D16L:$src,
-                                          bfin_subreg_lo16)),
-                          bfin_subreg_lo16)>;
+                                          lo16)),
+                          lo16)>;
 
 def : Pat<(sext_inreg D:$src, i16),
-          (MOVEsext (EXTRACT_SUBREG D:$src, bfin_subreg_lo16))>;
+          (MOVEsext (EXTRACT_SUBREG D:$src, lo16))>;
 
 def : Pat<(and D:$src, 0xffff),
-          (MOVEzext (EXTRACT_SUBREG D:$src, bfin_subreg_lo16))>;
+          (MOVEzext (EXTRACT_SUBREG D:$src, lo16))>;
 
 def : Pat<(i32 (anyext D16L:$src)),
           (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
                          (i16 (COPY_TO_REGCLASS D16L:$src, D16L)),
-                         bfin_subreg_lo16)>;
+                         lo16)>;
 
 // TODO Dreg = Dreg_byte (X/Z)
 
@@ -859,4 +859,4 @@ def : Pat<(BfinCall (i32 tglobaladdr:$dst)),
 def : Pat<(BfinCall (i32 texternalsym:$dst)),
           (CALLa texternalsym:$dst)>;
 def : Pat<(i16 (trunc D:$src)),
-          (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), bfin_subreg_lo16)>;
+          (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), lo16)>;
index 0571eb30052300f731158013775ef0a69815989d..5153aceb8f7362d8ca9f92dfb551de5841352a09 100644 (file)
@@ -177,11 +177,11 @@ void BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB,
 
   // We must split into halves
   BuildMI(MBB, I, DL,
-          TII.get(BF::LOAD16i), getSubReg(Reg, bfin_subreg_hi16))
+          TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16))
     .addImm((value >> 16) & 0xffff)
     .addReg(Reg, RegState::ImplicitDefine);
   BuildMI(MBB, I, DL,
-          TII.get(BF::LOAD16i), getSubReg(Reg, bfin_subreg_lo16))
+          TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16))
     .addImm(value & 0xffff)
     .addReg(Reg, RegState::ImplicitKill)
     .addReg(Reg, RegState::ImplicitDefine);
index 7cfb120bac587f0086b58ac9b36dcf4f8df2a45b..03c54507ff6eecb844ccfeff87cc97874dd11b05 100644 (file)
@@ -24,13 +24,6 @@ namespace llvm {
   class TargetInstrInfo;
   class Type;
 
-  // Subregister indices, keep in sync with BlackfinRegisterInfo.td
-  enum BfinSubregIdx {
-    bfin_subreg_lo16 = 1,
-    bfin_subreg_hi16 = 2,
-    bfin_subreg_lo32 = 3
-  };
-
   struct BlackfinRegisterInfo : public BlackfinGenRegisterInfo {
     BlackfinSubtarget &Subtarget;
     const TargetInstrInfo &TII;
index d396cc807e88ee347f80575587d18a04507bb661..2a7336c5b911318dd1f7b6e6c99429abf8e00ec8 100644 (file)
 //  Declarations that describe the Blackfin register file
 //===----------------------------------------------------------------------===//
 
-// Registers are identified with 3-bit group and 3-bit ID numbers.
+// Subregs are:
+// 1: .L
+// 2: .H
+// 3: .W (32 low bits of 40-bit accu)
+let Namespace = "BF" in {
+def lo16 : SubRegIndex { let NumberHack = 1; }
+def hi16 : SubRegIndex { let NumberHack = 2; }
+def lo32 : SubRegIndex { let NumberHack = 3; }
+}
 
+// Registers are identified with 3-bit group and 3-bit ID numbers.
 class BlackfinReg<string n> : Register<n> {
   field bits<3> Group;
   field bits<3> Num;
@@ -182,15 +191,6 @@ def LC1 : Ri<6, 3, "lc1">, DwarfRegNum<[47]>;
 def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>;
 def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>;
 
-// Subregs are:
-// 1: .L
-// 2: .H
-// 3: .W (32 low bits of 40-bit accu)
-// Keep in sync with enum in BlackfinRegisterInfo.h
-def bfin_subreg_lo16  : PatLeaf<(i32 1)>;
-def bfin_subreg_hi16  : PatLeaf<(i32 2)>;
-def bfin_subreg_32bit : PatLeaf<(i32 3)>;
-
 def : SubRegSet<1,
     [R0,  R1,  R2,  R3,  R4,  R5,  R6,  R7,
      P0,  P1,  P2,  P3,  P4,  P5,  SP,  FP,
index d4f412258f13a1d6457b3fe316430c60ffc58ad4..77756a3885c06f55374ecf89453f0bc46ef15c72 100644 (file)
@@ -2483,9 +2483,9 @@ X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
         unsigned DstReg = NewMI->getOperand(0).getReg();
         if (TargetRegisterInfo::isPhysicalRegister(DstReg))
           NewMI->getOperand(0).setReg(RI.getSubReg(DstReg,
-                                                   4/*x86_subreg_32bit*/));
+                                                   X86::x86_subreg_32bit));
         else
-          NewMI->getOperand(0).setSubReg(4/*x86_subreg_32bit*/);
+          NewMI->getOperand(0).setSubReg(X86::x86_subreg_32bit);
       }
       return NewMI;
     }
index 3291c0c30b9e03efe06002f5c836accd8e081049..a07f3ef2e973944da514792d815f8b6a07041250 100644 (file)
 //
 let Namespace = "X86" in {
 
+  // Subregister indices.
+  def x86_subreg_8bit    : SubRegIndex { let NumberHack = 1; }
+  def x86_subreg_8bit_hi : SubRegIndex { let NumberHack = 2; }
+  def x86_subreg_16bit   : SubRegIndex { let NumberHack = 3; }
+  def x86_subreg_32bit   : SubRegIndex { let NumberHack = 4; }
+
+  def x86_subreg_ss   : SubRegIndex { let NumberHack = 1; }
+  def x86_subreg_sd   : SubRegIndex { let NumberHack = 2; }
+  def x86_subreg_xmm  : SubRegIndex { let NumberHack = 3; }
+
+
   // In the register alias definitions below, we define which registers alias
   // which others.  We only specify which registers the small registers alias,
   // because the register file generator is smart enough to figure out that
@@ -224,15 +235,6 @@ let Namespace = "X86" in {
 // sub registers for each register.
 //
 
-def x86_subreg_8bit    : PatLeaf<(i32 1)>;
-def x86_subreg_8bit_hi : PatLeaf<(i32 2)>;
-def x86_subreg_16bit   : PatLeaf<(i32 3)>;
-def x86_subreg_32bit   : PatLeaf<(i32 4)>;
-
-def x86_subreg_ss   : PatLeaf<(i32 1)>;
-def x86_subreg_sd   : PatLeaf<(i32 2)>;
-def x86_subreg_xmm  : PatLeaf<(i32 3)>;
-
 def : SubRegSet<1, [AX, CX, DX, BX, SP,  BP,  SI,  DI,  
                     R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W],
                    [AL, CL, DL, BL, SPL, BPL, SIL, DIL, 
index a0bccfc5e57b10535678d33f27a10c4cfaef4a72..878ed09550aaba2e436ba0beeb0f11681a3f553d 100644 (file)
@@ -1057,6 +1057,11 @@ static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo,
     const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
     return EEVT::TypeSet(T.getRegisterVTs(R));
   }
+
+  if (R->isSubClassOf("SubRegIndex")) {
+    assert(ResNo == 0 && "SubRegisterIndices only produce one result!");
+    return EEVT::TypeSet();
+  }
   
   if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) {
     assert(ResNo == 0 && "This node only has one result!");
index 9d469a9acbee244c080f6f7599727227fb97475a..eb528eb02be84c38ac09f3345e656ee24775fe71 100644 (file)
@@ -224,6 +224,7 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
   if (// Handle register references.  Nothing to do here, they always match.
       LeafRec->isSubClassOf("RegisterClass") || 
       LeafRec->isSubClassOf("PointerLikeRegClass") ||
+      LeafRec->isSubClassOf("SubRegIndex") ||
       // Place holder for SRCVALUE nodes. Nothing to do here.
       LeafRec->getName() == "srcvalue")
     return;
@@ -597,6 +598,14 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
       ResultOps.push_back(NextRecordedOperandNo++);
       return;
     }
+
+    // Handle a subregister index. This is used for INSERT_SUBREG etc.
+    if (DI->getDef()->isSubClassOf("SubRegIndex")) {
+      std::string Value = getQualifiedName(DI->getDef());
+      AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
+      ResultOps.push_back(NextRecordedOperandNo++);
+      return;
+    }
   }
   
   errs() << "unhandled leaf node: \n";
index ce9d97b8ad33749fc31c9a46068bc598e1fe104a..9ec9e088424bacbd533d27b2543f0072b69ba13b 100644 (file)
@@ -31,7 +31,7 @@ namespace {
 struct InstructionMemo {
   std::string Name;
   const CodeGenRegisterClass *RC;
-  unsigned char SubRegNo;
+  std::string SubRegNo;
   std::vector<std::string>* PhysRegs;
 };
 
@@ -278,7 +278,7 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
     // For now, ignore instructions where the first operand is not an
     // output register.
     const CodeGenRegisterClass *DstRC = 0;
-    unsigned SubRegNo = ~0;
+    std::string SubRegNo;
     if (Op->getName() != "EXTRACT_SUBREG") {
       Record *Op0Rec = II.OperandList[0].Rec;
       if (!Op0Rec->isSubClassOf("RegisterClass"))
@@ -287,8 +287,11 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
       if (!DstRC)
         continue;
     } else {
-      SubRegNo = static_cast<IntInit*>(
-                 Dst->getChild(1)->getLeafValue())->getValue();
+      DefInit *SR = dynamic_cast<DefInit*>(Dst->getChild(1)->getLeafValue());
+      if (SR)
+        SubRegNo = getQualifiedName(SR->getDef());
+      else
+        SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString();
     }
 
     // Inspect the pattern.
@@ -437,7 +440,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) {
               }
               
               OS << "  return FastEmitInst_";
-              if (Memo.SubRegNo == (unsigned char)~0) {
+              if (Memo.SubRegNo.empty()) {
                 Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
                 OS << "(" << InstNS << Memo.Name << ", ";
                 OS << InstNS << Memo.RC->getName() << "RegisterClass";
@@ -448,7 +451,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) {
               } else {
                 OS << "extractsubreg(" << getName(RetVT);
                 OS << ", Op0, Op0IsKill, ";
-                OS << (unsigned)Memo.SubRegNo;
+                OS << Memo.SubRegNo;
                 OS << ");\n";
               }
               
@@ -532,7 +535,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) {
             
             OS << "  return FastEmitInst_";
             
-            if (Memo.SubRegNo == (unsigned char)~0) {
+            if (Memo.SubRegNo.empty()) {
               Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
               OS << "(" << InstNS << Memo.Name << ", ";
               OS << InstNS << Memo.RC->getName() << "RegisterClass";
@@ -542,7 +545,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) {
               OS << ");\n";
             } else {
               OS << "extractsubreg(RetVT, Op0, Op0IsKill, ";
-              OS << (unsigned)Memo.SubRegNo;
+              OS << Memo.SubRegNo;
               OS << ");\n";
             }
             
index fcf4123cefbe77105000789d2a4d6b81ae1ff71d..a5fabeab5a09e9e71b0826b3808bb7a458744ae3 100644 (file)
@@ -35,14 +35,31 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) {
 
   if (!Namespace.empty())
     OS << "namespace " << Namespace << " {\n";
-  OS << "  enum {\n    NoRegister,\n";
+  OS << "enum {\n  NoRegister,\n";
 
   for (unsigned i = 0, e = Registers.size(); i != e; ++i)
-    OS << "    " << Registers[i].getName() << ", \t// " << i+1 << "\n";
-  OS << "    NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
-  OS << "  };\n";
+    OS << "  " << Registers[i].getName() << ", \t// " << i+1 << "\n";
+  OS << "  NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
+  OS << "};\n";
   if (!Namespace.empty())
     OS << "}\n";
+
+  const std::vector<Record*> SubRegIndices =
+    Records.getAllDerivedDefinitions("SubRegIndex");
+  if (!SubRegIndices.empty()) {
+    OS << "\n// Subregister indices\n";
+    Namespace = SubRegIndices[0]->getValueAsString("Namespace");
+    if (!Namespace.empty())
+      OS << "namespace " << Namespace << " {\n";
+    OS << "enum {\n  NoSubRegister,\n";
+    for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
+      OS << "  " << SubRegIndices[i]->getName() << " = "
+         << SubRegIndices[i]->getValueAsInt("NumberHack") << ",\n";
+    OS << "  NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n";
+    OS << "};\n";
+    if (!Namespace.empty())
+      OS << "}\n";
+  }
   OS << "} // End llvm namespace \n";
 }