Support multiple ValueTypes per RegisterClass, needed for upcoming vector
authorNate Begeman <natebegeman@mac.com>
Thu, 1 Dec 2005 04:51:06 +0000 (04:51 +0000)
committerNate Begeman <natebegeman@mac.com>
Thu, 1 Dec 2005 04:51:06 +0000 (04:51 +0000)
work.  This change has no effect on generated code.

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

16 files changed:
include/llvm/Target/MRegisterInfo.h
lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
lib/Target/Alpha/AlphaRegisterInfo.td
lib/Target/IA64/IA64RegisterInfo.td
lib/Target/PowerPC/PPCRegisterInfo.td
lib/Target/Skeleton/SkeletonRegisterInfo.td
lib/Target/Sparc/SparcRegisterInfo.td
lib/Target/SparcV8/SparcV8RegisterInfo.td
lib/Target/SparcV9/SparcV9RegisterInfo.cpp
lib/Target/SparcV9/SparcV9RegisterInfo.td
lib/Target/Target.td
lib/Target/X86/X86RegisterInfo.td
utils/TableGen/CodeGenRegisters.h
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/DAGISelEmitter.cpp
utils/TableGen/RegisterInfoEmitter.cpp

index f7baba2ce602da5cd04c6ea62e8f51c99eb775f2..d17636d9a4d3e410c9ef2c05073bc4cbd1d4045f 100644 (file)
@@ -45,18 +45,15 @@ public:
   typedef const unsigned* const_iterator;
 
 private:
-  const MVT::ValueType VT;
+  const MVT::ValueType* VTs;
   const unsigned RegSize, Alignment;    // Size & Alignment of register in bytes
   const iterator RegsBegin, RegsEnd;
 public:
-  TargetRegisterClass(MVT::ValueType vt, unsigned RS, unsigned Al, iterator RB, iterator RE)
-    : VT(vt), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
+  TargetRegisterClass(const MVT::ValueType *vts, unsigned RS, unsigned Al,
+                      iterator RB, iterator RE)
+    : VTs(vts), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
   virtual ~TargetRegisterClass() {}     // Allow subclasses
 
-  /// getType - Return the declared value type for this register class.
-  ///
-  MVT::ValueType getType() const { return VT; }
-  
   // begin/end - Return all of the registers in this class.
   iterator       begin() const { return RegsBegin; }
   iterator         end() const { return RegsEnd; }
@@ -78,6 +75,15 @@ public:
     return false;
   }
 
+  /// hasType - return true if this TargetRegisterClass has the ValueType vt.
+  ///
+  bool hasType(MVT::ValueType vt) const {
+    for(int i = 0; VTs[i] != MVT::Other; ++i)
+      if (VTs[i] == vt)
+        return true;
+    return false;
+  }
+  
   /// allocation_order_begin/end - These methods define a range of registers
   /// which specify the registers in this class that are valid to register
   /// allocate, and the preferred order to allocate them in.  For example,
index f250a7bc050f5a006774c56d1496e549bf0b2df8..c1a7f47bbc31b1421b534af3e36e46df1f817838 100644 (file)
@@ -1208,7 +1208,7 @@ void SimpleSched::EmitNode(NodeInfo *NI) {
         // Pick the register class of the right type that contains this physreg.
         for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(),
              E = MRI.regclass_end(); I != E; ++I)
-          if ((*I)->getType() == Node->getValueType(0) &&
+          if ((*I)->hasType(Node->getValueType(0)) &&
               (*I)->contains(SrcReg)) {
             TRC = *I;
             break;
index b0884360861ab198d751582be354d92408748d2a..febf6fe2ff55952fa98322f5f5ce6c6386cae24e 100644 (file)
@@ -78,7 +78,7 @@ def F30 : FPR<30, "$f30">;  def F31 : FPR<31, "$f31">;
   // $28 is undefined after any and all calls
 
 /// Register classes
-def GPRC : RegisterClass<"Alpha", i64, 64,
+def GPRC : RegisterClass<"Alpha", [i64], 64,
      // Volatile
      [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22,
       R23, R24, R25, R28, 
@@ -102,7 +102,7 @@ def GPRC : RegisterClass<"Alpha", i64, 64,
   }];
 }
 
-def F4RC : RegisterClass<"Alpha", f32, 64, [F0, F1, 
+def F4RC : RegisterClass<"Alpha", [f32], 64, [F0, F1, 
         F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
         F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
         // Saved:
@@ -120,7 +120,7 @@ def F4RC : RegisterClass<"Alpha", f32, 64, [F0, F1,
   }];
 }
 
-def F8RC : RegisterClass<"Alpha", f64, 64, [F0, F1, 
+def F8RC : RegisterClass<"Alpha", [f64], 64, [F0, F1, 
         F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
         F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
         // Saved:
index 60cdf991a23b2c013db2c06087c0c5a53f7c7c31..03aba454635a50ac55bd4ffd297bab03c50c9a97 100644 (file)
@@ -232,7 +232,7 @@ def B6 : GR<0, "b6">;
 // FIXME/XXX  we also reserve r22 for calculating addresses
 // in IA64RegisterInfo.cpp
 
-def GR : RegisterClass<"IA64", i64, 64, 
+def GR : RegisterClass<"IA64", [i64], 64, 
        [
        
 //FIXME!: for readability, we don't want the out registers to be the first
@@ -282,7 +282,7 @@ def GR : RegisterClass<"IA64", i64, 64,
 
 
 // these are the scratch (+stacked) FP registers
-def FP : RegisterClass<"IA64", f64, 64, 
+def FP : RegisterClass<"IA64", [f64], 64, 
        [F6, F7, 
        F8, F9, F10, F11, F12, F13, F14, F15, 
        F32, F33, F34, F35, F36, F37, F38, F39, 
@@ -317,7 +317,7 @@ def FP : RegisterClass<"IA64", f64, 64,
 }
 
 // these are the predicate registers, p0 (1/TRUE) is not here
-def PR : RegisterClass<"IA64", i1, 64, 
+def PR : RegisterClass<"IA64", [i1], 64, 
 
 // for now, let's be wimps and only have the scratch predicate regs
  [p6, p7, p8, p9, p10, p11, p12, p13, p14, p15]> {
index d62045d8103fee934a54e3ee2e58dddff9bc1046..99813fdd2d10fa29380f9bd1ae1f3d1e33769dd8 100644 (file)
@@ -135,7 +135,7 @@ def VRSAVE: SPR<256, "VRsave">;
 /// Register classes
 // Allocate volatiles first
 // then nonvolatiles in reverse order since stmw/lmw save from rN to r31
-def GPRC : RegisterClass<"PPC", i32, 32,
+def GPRC : RegisterClass<"PPC", [i32], 32,
      [R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
       R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17,
       R16, R15, R14, R13, R31, R0, R1, LR]>
@@ -158,7 +158,7 @@ def GPRC : RegisterClass<"PPC", i32, 32,
     }
   }];
 }
-def G8RC : RegisterClass<"PPC", i64, 64,
+def G8RC : RegisterClass<"PPC", [i64], 64,
      [X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12,
       X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17,
       X16, X15, X14, X13, X31, X0, X1]>
@@ -184,15 +184,16 @@ def G8RC : RegisterClass<"PPC", i64, 64,
 
 
 
-def F8RC : RegisterClass<"PPC", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
+def F8RC : RegisterClass<"PPC", [f64], 64, [F0, F1, F2, F3, F4, F5, F6, F7,
   F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
   F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
-def F4RC : RegisterClass<"PPC", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7,
+def F4RC : RegisterClass<"PPC", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7,
   F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
   F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
 
-def VRRC : RegisterClass<"PPC", v4f32, 128, [V0, V1, V2, V3, V4, V5, V6, V7, V8,
-  V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23,
+def VRRC : RegisterClass<"PPC", [v4f32], 128, [V0, V1, V2, V3, V4, V5, V6, V7, 
+  V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23,
   V24, V25, V26, V27, V28, V29, V30, V31]>;
 
-def CRRC : RegisterClass<"PPC", i32, 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]>;
+def CRRC : RegisterClass<"PPC", [i32], 32, [CR0, CR1, CR5, CR6, CR7, CR2, 
+  CR3, CR4]>;
index 5313001ae55646a003b47530c36f0324afc050ff..41cef244c4fb53712f87406b6aecaf9b19324288 100644 (file)
@@ -89,10 +89,10 @@ def TBU : SPR<5, "TBU">;
 
 /// Register classes: one for floats and another for non-floats.
 ///
-def GPRC : RegisterClass<"Skeleton", i32, 32, [R0, R1, R2, R3, R4, R5, R6, R7,
+def GPRC : RegisterClass<"Skeleton", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7,
   R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21,
   R22, R23, R24, R25, R26, R27, R28, R29, R30, R31]>;
-def FPRC : RegisterClass<"Skeleton", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
+def FPRC : RegisterClass<"Skeleton", [f64], 64, [F0, F1, F2, F3, F4, F5, F6, F7,
   F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
   F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
 
index b328546959336fd111b401fcaec999a607f7a824..40eb185b71f334b1e1b52ab23d94d4a39810e132 100644 (file)
@@ -84,7 +84,7 @@ def Y   : Rs<0, "Y">;
 // FIXME: the register order should be defined in terms of the preferred
 // allocation order...
 //
-def IntRegs : RegisterClass<"V8", i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
+def IntRegs : RegisterClass<"V8", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7,
                                      I0, I1, I2, I3, I4, I5,
                                      G1,
                                      O0, O1, O2, O3, O4, O5, O7,
@@ -109,9 +109,9 @@ def IntRegs : RegisterClass<"V8", i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
   }];
 }
 
-def FPRegs : RegisterClass<"V8", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
+def FPRegs : RegisterClass<"V8", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
   F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
   F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
 
-def DFPRegs : RegisterClass<"V8", f64, 64, [D0, D1, D2, D3, D4, D5, D6, D7,
+def DFPRegs : RegisterClass<"V8", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7,
   D8, D9, D10, D11, D12, D13, D14, D15]>;
index b328546959336fd111b401fcaec999a607f7a824..40eb185b71f334b1e1b52ab23d94d4a39810e132 100644 (file)
@@ -84,7 +84,7 @@ def Y   : Rs<0, "Y">;
 // FIXME: the register order should be defined in terms of the preferred
 // allocation order...
 //
-def IntRegs : RegisterClass<"V8", i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
+def IntRegs : RegisterClass<"V8", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7,
                                      I0, I1, I2, I3, I4, I5,
                                      G1,
                                      O0, O1, O2, O3, O4, O5, O7,
@@ -109,9 +109,9 @@ def IntRegs : RegisterClass<"V8", i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
   }];
 }
 
-def FPRegs : RegisterClass<"V8", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
+def FPRegs : RegisterClass<"V8", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
   F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
   F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
 
-def DFPRegs : RegisterClass<"V8", f64, 64, [D0, D1, D2, D3, D4, D5, D6, D7,
+def DFPRegs : RegisterClass<"V8", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7,
   D8, D9, D10, D11, D12, D13, D14, D15]>;
index d2d0946053f1ddfb4139bc00d60bd47a69cf4a36..0ef9d34365f1863aae7971a612f0f9cfaca0a223 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "SparcV9RegisterInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/ValueTypes.h"
 using namespace llvm;
 
 namespace llvm {
@@ -42,8 +43,9 @@ namespace {
     SparcV9::g2, SparcV9::g3, SparcV9::g4, SparcV9::g5, SparcV9::g6,
     SparcV9::g7, SparcV9::o6
   };
+  const MVT::ValueType IRVTs[] = { MVT::i64, MVT::Other };
   struct IRClass : public TargetRegisterClass {
-    IRClass() : TargetRegisterClass(MVT::i64, 8, 8, IR, IR + 32) {}
+    IRClass() : TargetRegisterClass(IRVTs, 8, 8, IR, IR + 32) {}
   } IRInstance;
 
 
@@ -66,12 +68,13 @@ namespace {
     SparcV9::f58, SparcV9::f59, SparcV9::f60, SparcV9::f61,
     SparcV9::f62, SparcV9::f63
   };
+  const MVT::ValueType FRVTs[] = { MVT::f32, MVT::Other };
   // FIXME: The size is correct for the first 32 registers. The
   // latter 32 do not all really exist; you can only access every other
   // one (32, 34, ...), and they must contain double-fp or quad-fp
   // values... see below about the aliasing problems.
   struct FRClass : public TargetRegisterClass {
-    FRClass() : TargetRegisterClass(MVT::f32, 4, 8, FR, FR + 64) {}
+    FRClass() : TargetRegisterClass(FRVTs, 4, 8, FR, FR + 64) {}
   } FRInstance;
 
 
@@ -79,8 +82,9 @@ namespace {
   const unsigned ICCR[] = {
     SparcV9::xcc, SparcV9::icc, SparcV9::ccr
   };
+  const MVT::ValueType ICCRVTs[] = { MVT::i1, MVT::Other };
   struct ICCRClass : public TargetRegisterClass {
-    ICCRClass() : TargetRegisterClass(MVT::i1, 1, 8, ICCR, ICCR + 3) {}
+    ICCRClass() : TargetRegisterClass(ICCRVTs, 1, 8, ICCR, ICCR + 3) {}
   } ICCRInstance;
 
 
@@ -88,8 +92,9 @@ namespace {
   const unsigned FCCR[] = {
     SparcV9::fcc0, SparcV9::fcc1, SparcV9::fcc2, SparcV9::fcc3
   };
+  const MVT::ValueType FCCRVTs[] = { MVT::i1, MVT::Other };
   struct FCCRClass : public TargetRegisterClass {
-    FCCRClass() : TargetRegisterClass(MVT::i1, 1, 8, FCCR, FCCR + 4) {}
+    FCCRClass() : TargetRegisterClass(FCCRVTs, 1, 8, FCCR, FCCR + 4) {}
   } FCCRInstance;
 
 
@@ -97,8 +102,9 @@ namespace {
   const unsigned SR[] = {
     SparcV9::fsr
   };
+  const MVT::ValueType SRVTs[] = { MVT::i64, MVT::Other };
   struct SRClass : public TargetRegisterClass {
-    SRClass() : TargetRegisterClass(MVT::i64, 8, 8, SR, SR + 1) {}
+    SRClass() : TargetRegisterClass(SRVTs, 8, 8, SR, SR + 1) {}
   } SRInstance;
 
 
index a248bc5a2cd268dd53c0c13f9ca3cbb0dd824813..c2266511c02a326b18b4beedd3d3f519ac8be3ea 100644 (file)
@@ -43,7 +43,7 @@ let Namespace = "SparcV9" in {
 // FIXME: the register order should be defined in terms of the preferred
 // allocation order...
 //
-def IntRegs : RegisterClass<"V9", i64, 64, [G0, G1, G2, G3, G4, G5, G6, G7,
+def IntRegs : RegisterClass<"V9", [i64], 64, [G0, G1, G2, G3, G4, G5, G6, G7,
                                      O0, O1, O2, O3, O4, O5, O6, O7,
                                      L0, L1, L2, L3, L4, L5, L6, L7,
                                      I0, I1, I2, I3, I4, I5, I6, I7]>;
index eeda4f9fe06e7f5e42464781b5282ca4eeb29f88..46a1b470c492c0909617e1aa95fcf059e661a564 100644 (file)
@@ -90,19 +90,22 @@ class RegisterGroup<string n, list<Register> aliases> : Register<n> {
 // register classes.  This also defines the default allocation order of
 // registers by register allocators.
 //
-class RegisterClass<string namespace, ValueType regType, int alignment,
+class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
                     list<Register> regList> {
   string Namespace = namespace;
 
   // RegType - Specify the ValueType of the registers in this register class.
   // Note that all registers in a register class must have the same ValueType.
   //
-  ValueType RegType = regType;
+  list<ValueType> RegTypes = regTypes;
+
+  // Size - Specify the spill size in bits of the registers.  A default value of
+  // zero lets tablgen pick an appropriate size.
+  int Size = 0;
 
   // Alignment - Specify the alignment required of the registers when they are
   // stored or loaded to memory.
   //
-  int Size = RegType.Size;
   int Alignment = alignment;
 
   // MemberList - Specify which registers are in this class.  If the
index 64571525cd454920c56f319e4c5ea63dcf959573..139ebd7fd71541bad2c47dc52877e581206911b3 100644 (file)
@@ -72,9 +72,9 @@ let Namespace = "X86" in {
 // dependences between upper and lower parts of the register.  BL and BH are
 // last because they are call clobbered. Both Athlon and P4 chips suffer this
 // issue.
-def R8  : RegisterClass<"X86", i8,  8, [AL, CL, DL, AH, CH, DH, BL, BH]>;
+def R8  : RegisterClass<"X86", [i8],  8, [AL, CL, DL, AH, CH, DH, BL, BH]>;
 
-def R16 : RegisterClass<"X86", i16, 16, [AX, CX, DX, SI, DI, BX, BP, SP]> {
+def R16 : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP]> {
   let MethodProtos = [{
     iterator allocation_order_end(MachineFunction &MF) const;
   }];
@@ -89,7 +89,8 @@ def R16 : RegisterClass<"X86", i16, 16, [AX, CX, DX, SI, DI, BX, BP, SP]> {
   }];
 }
 
-def R32 : RegisterClass<"X86", i32, 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> {
+def R32 : RegisterClass<"X86", [i32], 32, 
+                        [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> {
   let MethodProtos = [{
     iterator allocation_order_end(MachineFunction &MF) const;
   }];
@@ -106,9 +107,9 @@ def R32 : RegisterClass<"X86", i32, 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]
 
 // V4F4, the 4 x f32 class, and V2F8, the 2 x f64 class, which we will use for
 // Scalar SSE2 floating point support.
-def V4F4 : RegisterClass<"X86", f32, 32,
+def V4F4 : RegisterClass<"X86", [f32], 32,
                          [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>;
-def V2F8 : RegisterClass<"X86", f64, 64,
+def V2F8 : RegisterClass<"X86", [f64], 64,
                          [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>;
 
 // FIXME: This sets up the floating point register files as though they are f64
@@ -117,12 +118,12 @@ def V2F8 : RegisterClass<"X86", f64, 64,
 // faster on common hardware.  In reality, this should be controlled by a
 // command line option or something.
 
-def RFP : RegisterClass<"X86", f64, 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
+def RFP : RegisterClass<"X86", [f64], 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
 
 // Floating point stack registers (these are not allocatable by the
 // register allocator - the floating point stackifier is responsible
 // for transforming FPn allocations to STn registers)
-def RST : RegisterClass<"X86", f64, 32,
+def RST : RegisterClass<"X86", [f64], 32,
                         [ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7]> {
     let MethodProtos = [{
     iterator allocation_order_end(MachineFunction &MF) const;
index 6a9b7907bd83fc3306142e088eb73fd5be82b0d6..d719d89d625706f7c893ab996ab8dc7994cb03e8 100644 (file)
@@ -35,13 +35,20 @@ namespace llvm {
     Record *TheDef;
     std::string Namespace;
     std::vector<Record*> Elements;
+    std::vector<MVT::ValueType> VTs;
     unsigned SpillSize;
     unsigned SpillAlignment;
-    MVT::ValueType VT;
     std::string MethodProtos, MethodBodies;
 
     const std::string &getName() const;
 
+    const MVT::ValueType getValueTypeNum(unsigned VTNum) const {
+      if (VTNum < VTs.size())
+        return VTs[VTNum];
+      assert(0 && "VTNum greater than number of ValueTypes in RegClass!");
+      abort();
+    }
+
     CodeGenRegisterClass(Record *R);
   };
 }
index 73730d18a8024d762da45e753773b4490f02d3bf..51aad4fd3bb3f590dc61bdb9df1430f992603bec 100644 (file)
@@ -154,13 +154,15 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
     R->setName("AnonRegClass_"+utostr(AnonCounter++));
   } 
   
-  Namespace = R->getValueAsString("Namespace");
-  SpillSize = R->getValueAsInt("Size");
-  SpillAlignment = R->getValueAsInt("Alignment");
-  VT = getValueType(R->getValueAsDef("RegType"));
-
-  MethodBodies = R->getValueAsCode("MethodBodies");
-  MethodProtos = R->getValueAsCode("MethodProtos");
+  std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
+  for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
+    Record *Type = TypeList[i];
+    if (!Type->isSubClassOf("ValueType"))
+      throw "RegTypes list member '" + Type->getName() +
+        "' does not derive from the ValueType class!";
+    VTs.push_back(getValueType(Type));
+  }
+  assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!");
   
   std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList");
   for (unsigned i = 0, e = RegList.size(); i != e; ++i) {
@@ -170,6 +172,15 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
             "' does not derive from the Register class!";
     Elements.push_back(Reg);
   }
+  
+  // Allow targets to override the size in bits of the RegisterClass.
+  unsigned Size = R->getValueAsInt("Size");
+
+  Namespace = R->getValueAsString("Namespace");
+  SpillSize = Size ? Size : MVT::getSizeInBits(VTs[0]);
+  SpillAlignment = R->getValueAsInt("Alignment");
+  MethodBodies = R->getValueAsCode("MethodBodies");
+  MethodProtos = R->getValueAsCode("MethodProtos");
 }
 
 const std::string &CodeGenRegisterClass::getName() const {
@@ -179,7 +190,8 @@ const std::string &CodeGenRegisterClass::getName() const {
 void CodeGenTarget::ReadLegalValueTypes() const {
   const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
   for (unsigned i = 0, e = RCs.size(); i != e; ++i)
-    LegalValueTypes.push_back(RCs[i].VT);
+    for (unsigned ri = 0, re = RCs[i].VTs.size(); ri != re; ++ri)
+      LegalValueTypes.push_back(RCs[i].VTs[ri]);
   
   // Remove duplicates.
   std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
index 4b40561b2689a3ebf792fe23ec34b39e5f761f5d..8e6095c1063fc9fc80dc36f04a480b0e21b62acb 100644 (file)
@@ -455,7 +455,9 @@ static unsigned char getIntrinsicType(Record *R, bool NotRegisters,
   // Check to see if this is a register or a register class...
   if (R->isSubClassOf("RegisterClass")) {
     if (NotRegisters) return MVT::isUnknown;
-    return getValueType(R->getValueAsDef("RegType"));
+    const CodeGenRegisterClass &RC = 
+      TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(R);
+    return RC.getValueTypeNum(0);
   } else if (R->isSubClassOf("PatFrag")) {
     // Pattern fragment types will be resolved when they are inlined.
     return MVT::isUnknown;
@@ -537,8 +539,9 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
 
     const CodeGenRegisterClass &RC = 
       TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(ResultNode);
-    
-    bool MadeChange = UpdateNodeType(RC.VT, TP);
+
+    // Get the first ValueType in the RegClass, it's as good as any.
+    bool MadeChange = UpdateNodeType(RC.getValueTypeNum(0), TP);
 
     if (getNumChildren() != Inst.getNumOperands())
       TP.error("Instruction '" + getOperator()->getName() + " expects " +
@@ -550,7 +553,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
       if (OperandNode->isSubClassOf("RegisterClass")) {
         const CodeGenRegisterClass &RC = 
           TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(OperandNode);
-        VT = RC.VT;
+        VT = RC.getValueTypeNum(0);
       } else if (OperandNode->isSubClassOf("Operand")) {
         VT = getValueType(OperandNode->getValueAsDef("Type"));
       } else {
@@ -1672,7 +1675,8 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
        << ".Val)) goto P" << PatternNo << "Fail;\n";
 }
 
-/// getRegisterValueType - Look up and return ValueType of specified record
+/// getRegisterValueType - Look up and return the first ValueType of specified 
+/// RegisterClass record
 static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) {
   const std::vector<CodeGenRegisterClass> &RegisterClasses =
     T.getRegisterClasses();
@@ -1681,7 +1685,7 @@ static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) {
     const CodeGenRegisterClass &RC = RegisterClasses[i];
     for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
       if (R == RC.Elements[ei]) {
-        return RC.VT;
+        return RC.getValueTypeNum(0);
       }
     }
   }
index 5c3cb8db80864dc831bd9e1403957db1665fc461..13a85f784fa34b9c05b86ae775da70fd9f1bc8f6 100644 (file)
@@ -109,6 +109,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
   // belongs to.
   std::multimap<Record*, const CodeGenRegisterClass*> RegClassesBelongedTo;
 
+  // Emit the register enum value arrays for each RegisterClass
   for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
     const CodeGenRegisterClass &RC = RegisterClasses[rc];
 
@@ -127,6 +128,22 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
     }
     OS << "\n  };\n\n";
   }
+  
+  // Emit the ValueType arrays for each RegisterClass
+  for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+    const CodeGenRegisterClass &RC = RegisterClasses[rc];
+    
+    // Give the register class a legal C name if it's anonymous.
+    std::string Name = RC.TheDef->getName() + "VTs";
+    
+    // Emit the register list now.
+    OS << "  // " << Name 
+      << " Register Class Value Types...\n  const MVT::ValueType " << Name
+      << "[] = {\n    ";
+    for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i)
+      OS << "MVT::" << RC.VTs[i] << ", ";
+    OS << "MVT::Other\n  };\n\n";
+  }
   OS << "}  // end anonymous namespace\n\n";
   
   // Now that all of the structs have been emitted, emit the instances.
@@ -140,8 +157,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
     for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
       const CodeGenRegisterClass &RC = RegisterClasses[i];
       OS << RC.MethodBodies << "\n";
-      OS << RC.getName() << "Class::" << RC.getName()
-         << "Class()  : TargetRegisterClass(MVT::" << getEnumName(RC.VT) << ","
+      OS << RC.getName() << "Class::" << RC.getName() 
+         << "Class()  : TargetRegisterClass(" << RC.getName() + "VTs" << ", "
          << RC.SpillSize/8 << ", "
          << RC.SpillAlignment/8 << ", " << RC.getName() << ", "
          << RC.getName() << " + " << RC.Elements.size() << ") {}\n";