mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	Support multiple ValueTypes per RegisterClass, needed for upcoming vector
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
This commit is contained in:
		| @@ -45,18 +45,15 @@ public: | |||||||
|   typedef const unsigned* const_iterator; |   typedef const unsigned* const_iterator; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|   const MVT::ValueType VT; |   const MVT::ValueType* VTs; | ||||||
|   const unsigned RegSize, Alignment;    // Size & Alignment of register in bytes |   const unsigned RegSize, Alignment;    // Size & Alignment of register in bytes | ||||||
|   const iterator RegsBegin, RegsEnd; |   const iterator RegsBegin, RegsEnd; | ||||||
| public: | public: | ||||||
|   TargetRegisterClass(MVT::ValueType vt, unsigned RS, unsigned Al, iterator RB, iterator RE) |   TargetRegisterClass(const MVT::ValueType *vts, unsigned RS, unsigned Al, | ||||||
|     : VT(vt), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} |                       iterator RB, iterator RE) | ||||||
|  |     : VTs(vts), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} | ||||||
|   virtual ~TargetRegisterClass() {}     // Allow subclasses |   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. |   // begin/end - Return all of the registers in this class. | ||||||
|   iterator       begin() const { return RegsBegin; } |   iterator       begin() const { return RegsBegin; } | ||||||
|   iterator         end() const { return RegsEnd; } |   iterator         end() const { return RegsEnd; } | ||||||
| @@ -78,6 +75,15 @@ public: | |||||||
|     return false; |     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 |   /// allocation_order_begin/end - These methods define a range of registers | ||||||
|   /// which specify the registers in this class that are valid to register |   /// which specify the registers in this class that are valid to register | ||||||
|   /// allocate, and the preferred order to allocate them in.  For example, |   /// allocate, and the preferred order to allocate them in.  For example, | ||||||
|   | |||||||
| @@ -1208,7 +1208,7 @@ void SimpleSched::EmitNode(NodeInfo *NI) { | |||||||
|         // Pick the register class of the right type that contains this physreg. |         // Pick the register class of the right type that contains this physreg. | ||||||
|         for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), |         for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(), | ||||||
|              E = MRI.regclass_end(); I != E; ++I) |              E = MRI.regclass_end(); I != E; ++I) | ||||||
|           if ((*I)->getType() == Node->getValueType(0) && |           if ((*I)->hasType(Node->getValueType(0)) && | ||||||
|               (*I)->contains(SrcReg)) { |               (*I)->contains(SrcReg)) { | ||||||
|             TRC = *I; |             TRC = *I; | ||||||
|             break; |             break; | ||||||
|   | |||||||
| @@ -78,7 +78,7 @@ def F30 : FPR<30, "$f30">;  def F31 : FPR<31, "$f31">; | |||||||
|   // $28 is undefined after any and all calls |   // $28 is undefined after any and all calls | ||||||
|  |  | ||||||
| /// Register classes | /// Register classes | ||||||
| def GPRC : RegisterClass<"Alpha", i64, 64, | def GPRC : RegisterClass<"Alpha", [i64], 64, | ||||||
|      // Volatile |      // Volatile | ||||||
|      [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, |      [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, | ||||||
|       R23, R24, R25, R28,  |       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, |         F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, | ||||||
|         F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, |         F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, | ||||||
|         // Saved: |         // 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, |         F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, | ||||||
|         F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, |         F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, | ||||||
|         // Saved: |         // Saved: | ||||||
|   | |||||||
| @@ -232,7 +232,7 @@ def B6 : GR<0, "b6">; | |||||||
| // FIXME/XXX  we also reserve r22 for calculating addresses | // FIXME/XXX  we also reserve r22 for calculating addresses | ||||||
| // in IA64RegisterInfo.cpp | // 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 | //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 | // these are the scratch (+stacked) FP registers | ||||||
| def FP : RegisterClass<"IA64", f64, 64,  | def FP : RegisterClass<"IA64", [f64], 64,  | ||||||
|        [F6, F7,  |        [F6, F7,  | ||||||
| 	F8, F9, F10, F11, F12, F13, F14, F15,  | 	F8, F9, F10, F11, F12, F13, F14, F15,  | ||||||
| 	F32, F33, F34, F35, F36, F37, F38, F39,  | 	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 | // 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 | // for now, let's be wimps and only have the scratch predicate regs | ||||||
|  [p6, p7, p8, p9, p10, p11, p12, p13, p14, p15]> { |  [p6, p7, p8, p9, p10, p11, p12, p13, p14, p15]> { | ||||||
|   | |||||||
| @@ -135,7 +135,7 @@ def VRSAVE: SPR<256, "VRsave">; | |||||||
| /// Register classes | /// Register classes | ||||||
| // Allocate volatiles first | // Allocate volatiles first | ||||||
| // then nonvolatiles in reverse order since stmw/lmw save from rN to r31 | // 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, |      [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, |       R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17, | ||||||
|       R16, R15, R14, R13, R31, R0, R1, LR]> |       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, |      [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, |       X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17, | ||||||
|       X16, X15, X14, X13, X31, X0, X1]> |       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, |   F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, | ||||||
|   F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; |   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, |   F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, | ||||||
|   F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; |   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, | def VRRC : RegisterClass<"PPC", [v4f32], 128, [V0, V1, V2, V3, V4, V5, V6, V7,  | ||||||
|   V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, |   V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, | ||||||
|   V24, V25, V26, V27, V28, V29, V30, V31]>; |   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]>; | ||||||
|   | |||||||
| @@ -89,10 +89,10 @@ def TBU : SPR<5, "TBU">; | |||||||
|  |  | ||||||
| /// Register classes: one for floats and another for non-floats. | /// 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, |   R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, | ||||||
|   R22, R23, R24, R25, R26, R27, R28, R29, R30, R31]>; |   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, |   F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, | ||||||
|   F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; |   F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -84,7 +84,7 @@ def Y   : Rs<0, "Y">; | |||||||
| // FIXME: the register order should be defined in terms of the preferred | // FIXME: the register order should be defined in terms of the preferred | ||||||
| // allocation order... | // 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, |                                      I0, I1, I2, I3, I4, I5, | ||||||
|                                      G1, |                                      G1, | ||||||
|                                      O0, O1, O2, O3, O4, O5, O7, |                                      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, |   F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, | ||||||
|   F23, F24, F25, F26, F27, F28, F29, F30, F31]>; |   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]>; |   D8, D9, D10, D11, D12, D13, D14, D15]>; | ||||||
|   | |||||||
| @@ -84,7 +84,7 @@ def Y   : Rs<0, "Y">; | |||||||
| // FIXME: the register order should be defined in terms of the preferred | // FIXME: the register order should be defined in terms of the preferred | ||||||
| // allocation order... | // 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, |                                      I0, I1, I2, I3, I4, I5, | ||||||
|                                      G1, |                                      G1, | ||||||
|                                      O0, O1, O2, O3, O4, O5, O7, |                                      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, |   F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, | ||||||
|   F23, F24, F25, F26, F27, F28, F29, F30, F31]>; |   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]>; |   D8, D9, D10, D11, D12, D13, D14, D15]>; | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ | |||||||
|  |  | ||||||
| #include "SparcV9RegisterInfo.h" | #include "SparcV9RegisterInfo.h" | ||||||
| #include "llvm/CodeGen/MachineFunction.h" | #include "llvm/CodeGen/MachineFunction.h" | ||||||
|  | #include "llvm/CodeGen/ValueTypes.h" | ||||||
| using namespace llvm; | using namespace llvm; | ||||||
|  |  | ||||||
| namespace llvm { | namespace llvm { | ||||||
| @@ -42,8 +43,9 @@ namespace { | |||||||
|     SparcV9::g2, SparcV9::g3, SparcV9::g4, SparcV9::g5, SparcV9::g6, |     SparcV9::g2, SparcV9::g3, SparcV9::g4, SparcV9::g5, SparcV9::g6, | ||||||
|     SparcV9::g7, SparcV9::o6 |     SparcV9::g7, SparcV9::o6 | ||||||
|   }; |   }; | ||||||
|  |   const MVT::ValueType IRVTs[] = { MVT::i64, MVT::Other }; | ||||||
|   struct IRClass : public TargetRegisterClass { |   struct IRClass : public TargetRegisterClass { | ||||||
|     IRClass() : TargetRegisterClass(MVT::i64, 8, 8, IR, IR + 32) {} |     IRClass() : TargetRegisterClass(IRVTs, 8, 8, IR, IR + 32) {} | ||||||
|   } IRInstance; |   } IRInstance; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -66,12 +68,13 @@ namespace { | |||||||
|     SparcV9::f58, SparcV9::f59, SparcV9::f60, SparcV9::f61, |     SparcV9::f58, SparcV9::f59, SparcV9::f60, SparcV9::f61, | ||||||
|     SparcV9::f62, SparcV9::f63 |     SparcV9::f62, SparcV9::f63 | ||||||
|   }; |   }; | ||||||
|  |   const MVT::ValueType FRVTs[] = { MVT::f32, MVT::Other }; | ||||||
|   // FIXME: The size is correct for the first 32 registers. The |   // FIXME: The size is correct for the first 32 registers. The | ||||||
|   // latter 32 do not all really exist; you can only access every other |   // 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 |   // one (32, 34, ...), and they must contain double-fp or quad-fp | ||||||
|   // values... see below about the aliasing problems. |   // values... see below about the aliasing problems. | ||||||
|   struct FRClass : public TargetRegisterClass { |   struct FRClass : public TargetRegisterClass { | ||||||
|     FRClass() : TargetRegisterClass(MVT::f32, 4, 8, FR, FR + 64) {} |     FRClass() : TargetRegisterClass(FRVTs, 4, 8, FR, FR + 64) {} | ||||||
|   } FRInstance; |   } FRInstance; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -79,8 +82,9 @@ namespace { | |||||||
|   const unsigned ICCR[] = { |   const unsigned ICCR[] = { | ||||||
|     SparcV9::xcc, SparcV9::icc, SparcV9::ccr |     SparcV9::xcc, SparcV9::icc, SparcV9::ccr | ||||||
|   }; |   }; | ||||||
|  |   const MVT::ValueType ICCRVTs[] = { MVT::i1, MVT::Other }; | ||||||
|   struct ICCRClass : public TargetRegisterClass { |   struct ICCRClass : public TargetRegisterClass { | ||||||
|     ICCRClass() : TargetRegisterClass(MVT::i1, 1, 8, ICCR, ICCR + 3) {} |     ICCRClass() : TargetRegisterClass(ICCRVTs, 1, 8, ICCR, ICCR + 3) {} | ||||||
|   } ICCRInstance; |   } ICCRInstance; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -88,8 +92,9 @@ namespace { | |||||||
|   const unsigned FCCR[] = { |   const unsigned FCCR[] = { | ||||||
|     SparcV9::fcc0, SparcV9::fcc1, SparcV9::fcc2, SparcV9::fcc3 |     SparcV9::fcc0, SparcV9::fcc1, SparcV9::fcc2, SparcV9::fcc3 | ||||||
|   }; |   }; | ||||||
|  |   const MVT::ValueType FCCRVTs[] = { MVT::i1, MVT::Other }; | ||||||
|   struct FCCRClass : public TargetRegisterClass { |   struct FCCRClass : public TargetRegisterClass { | ||||||
|     FCCRClass() : TargetRegisterClass(MVT::i1, 1, 8, FCCR, FCCR + 4) {} |     FCCRClass() : TargetRegisterClass(FCCRVTs, 1, 8, FCCR, FCCR + 4) {} | ||||||
|   } FCCRInstance; |   } FCCRInstance; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -97,8 +102,9 @@ namespace { | |||||||
|   const unsigned SR[] = { |   const unsigned SR[] = { | ||||||
|     SparcV9::fsr |     SparcV9::fsr | ||||||
|   }; |   }; | ||||||
|  |   const MVT::ValueType SRVTs[] = { MVT::i64, MVT::Other }; | ||||||
|   struct SRClass : public TargetRegisterClass { |   struct SRClass : public TargetRegisterClass { | ||||||
|     SRClass() : TargetRegisterClass(MVT::i64, 8, 8, SR, SR + 1) {} |     SRClass() : TargetRegisterClass(SRVTs, 8, 8, SR, SR + 1) {} | ||||||
|   } SRInstance; |   } SRInstance; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ let Namespace = "SparcV9" in { | |||||||
| // FIXME: the register order should be defined in terms of the preferred | // FIXME: the register order should be defined in terms of the preferred | ||||||
| // allocation order... | // 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, |                                      O0, O1, O2, O3, O4, O5, O6, O7, | ||||||
|                                      L0, L1, L2, L3, L4, L5, L6, L7, |                                      L0, L1, L2, L3, L4, L5, L6, L7, | ||||||
|                                      I0, I1, I2, I3, I4, I5, I6, I7]>; |                                      I0, I1, I2, I3, I4, I5, I6, I7]>; | ||||||
|   | |||||||
| @@ -90,19 +90,22 @@ class RegisterGroup<string n, list<Register> aliases> : Register<n> { | |||||||
| // register classes.  This also defines the default allocation order of | // register classes.  This also defines the default allocation order of | ||||||
| // registers by register allocators. | // registers by register allocators. | ||||||
| // | // | ||||||
| class RegisterClass<string namespace, ValueType regType, int alignment, | class RegisterClass<string namespace, list<ValueType> regTypes, int alignment, | ||||||
|                     list<Register> regList> { |                     list<Register> regList> { | ||||||
|   string Namespace = namespace; |   string Namespace = namespace; | ||||||
|  |  | ||||||
|   // RegType - Specify the ValueType of the registers in this register class. |   // RegType - Specify the ValueType of the registers in this register class. | ||||||
|   // Note that all registers in a register class must have the same ValueType. |   // 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 |   // Alignment - Specify the alignment required of the registers when they are | ||||||
|   // stored or loaded to memory. |   // stored or loaded to memory. | ||||||
|   // |   // | ||||||
|   int Size = RegType.Size; |  | ||||||
|   int Alignment = alignment; |   int Alignment = alignment; | ||||||
|  |  | ||||||
|   // MemberList - Specify which registers are in this class.  If the |   // MemberList - Specify which registers are in this class.  If the | ||||||
|   | |||||||
| @@ -72,9 +72,9 @@ let Namespace = "X86" in { | |||||||
| // dependences between upper and lower parts of the register.  BL and BH are | // 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 | // last because they are call clobbered. Both Athlon and P4 chips suffer this | ||||||
| // issue. | // 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 = [{ |   let MethodProtos = [{ | ||||||
|     iterator allocation_order_end(MachineFunction &MF) const; |     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 = [{ |   let MethodProtos = [{ | ||||||
|     iterator allocation_order_end(MachineFunction &MF) const; |     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 | // V4F4, the 4 x f32 class, and V2F8, the 2 x f64 class, which we will use for | ||||||
| // Scalar SSE2 floating point support. | // 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]>; |                          [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]>; |                          [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>; | ||||||
|  |  | ||||||
| // FIXME: This sets up the floating point register files as though they are f64 | // 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 | // faster on common hardware.  In reality, this should be controlled by a | ||||||
| // command line option or something. | // 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 | // Floating point stack registers (these are not allocatable by the | ||||||
| // register allocator - the floating point stackifier is responsible | // register allocator - the floating point stackifier is responsible | ||||||
| // for transforming FPn allocations to STn registers) | // 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]> { |                         [ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7]> { | ||||||
|     let MethodProtos = [{ |     let MethodProtos = [{ | ||||||
|     iterator allocation_order_end(MachineFunction &MF) const; |     iterator allocation_order_end(MachineFunction &MF) const; | ||||||
|   | |||||||
| @@ -35,13 +35,20 @@ namespace llvm { | |||||||
|     Record *TheDef; |     Record *TheDef; | ||||||
|     std::string Namespace; |     std::string Namespace; | ||||||
|     std::vector<Record*> Elements; |     std::vector<Record*> Elements; | ||||||
|  |     std::vector<MVT::ValueType> VTs; | ||||||
|     unsigned SpillSize; |     unsigned SpillSize; | ||||||
|     unsigned SpillAlignment; |     unsigned SpillAlignment; | ||||||
|     MVT::ValueType VT; |  | ||||||
|     std::string MethodProtos, MethodBodies; |     std::string MethodProtos, MethodBodies; | ||||||
|  |  | ||||||
|     const std::string &getName() const; |     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); |     CodeGenRegisterClass(Record *R); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -154,13 +154,15 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) { | |||||||
|     R->setName("AnonRegClass_"+utostr(AnonCounter++)); |     R->setName("AnonRegClass_"+utostr(AnonCounter++)); | ||||||
|   }  |   }  | ||||||
|    |    | ||||||
|   Namespace = R->getValueAsString("Namespace"); |   std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes"); | ||||||
|   SpillSize = R->getValueAsInt("Size"); |   for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { | ||||||
|   SpillAlignment = R->getValueAsInt("Alignment"); |     Record *Type = TypeList[i]; | ||||||
|   VT = getValueType(R->getValueAsDef("RegType")); |     if (!Type->isSubClassOf("ValueType")) | ||||||
|  |       throw "RegTypes list member '" + Type->getName() + | ||||||
|   MethodBodies = R->getValueAsCode("MethodBodies"); |         "' does not derive from the ValueType class!"; | ||||||
|   MethodProtos = R->getValueAsCode("MethodProtos"); |     VTs.push_back(getValueType(Type)); | ||||||
|  |   } | ||||||
|  |   assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!"); | ||||||
|    |    | ||||||
|   std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList"); |   std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList"); | ||||||
|   for (unsigned i = 0, e = RegList.size(); i != e; ++i) { |   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!"; |             "' does not derive from the Register class!"; | ||||||
|     Elements.push_back(Reg); |     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 { | const std::string &CodeGenRegisterClass::getName() const { | ||||||
| @@ -179,7 +190,8 @@ const std::string &CodeGenRegisterClass::getName() const { | |||||||
| void CodeGenTarget::ReadLegalValueTypes() const { | void CodeGenTarget::ReadLegalValueTypes() const { | ||||||
|   const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses(); |   const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses(); | ||||||
|   for (unsigned i = 0, e = RCs.size(); i != e; ++i) |   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. |   // Remove duplicates. | ||||||
|   std::sort(LegalValueTypes.begin(), LegalValueTypes.end()); |   std::sort(LegalValueTypes.begin(), LegalValueTypes.end()); | ||||||
|   | |||||||
| @@ -455,7 +455,9 @@ static unsigned char getIntrinsicType(Record *R, bool NotRegisters, | |||||||
|   // Check to see if this is a register or a register class... |   // Check to see if this is a register or a register class... | ||||||
|   if (R->isSubClassOf("RegisterClass")) { |   if (R->isSubClassOf("RegisterClass")) { | ||||||
|     if (NotRegisters) return MVT::isUnknown; |     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")) { |   } else if (R->isSubClassOf("PatFrag")) { | ||||||
|     // Pattern fragment types will be resolved when they are inlined. |     // Pattern fragment types will be resolved when they are inlined. | ||||||
|     return MVT::isUnknown; |     return MVT::isUnknown; | ||||||
| @@ -538,7 +540,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { | |||||||
|     const CodeGenRegisterClass &RC =  |     const CodeGenRegisterClass &RC =  | ||||||
|       TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(ResultNode); |       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()) |     if (getNumChildren() != Inst.getNumOperands()) | ||||||
|       TP.error("Instruction '" + getOperator()->getName() + " expects " + |       TP.error("Instruction '" + getOperator()->getName() + " expects " + | ||||||
| @@ -550,7 +553,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { | |||||||
|       if (OperandNode->isSubClassOf("RegisterClass")) { |       if (OperandNode->isSubClassOf("RegisterClass")) { | ||||||
|         const CodeGenRegisterClass &RC =  |         const CodeGenRegisterClass &RC =  | ||||||
|           TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(OperandNode); |           TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(OperandNode); | ||||||
|         VT = RC.VT; |         VT = RC.getValueTypeNum(0); | ||||||
|       } else if (OperandNode->isSubClassOf("Operand")) { |       } else if (OperandNode->isSubClassOf("Operand")) { | ||||||
|         VT = getValueType(OperandNode->getValueAsDef("Type")); |         VT = getValueType(OperandNode->getValueAsDef("Type")); | ||||||
|       } else { |       } else { | ||||||
| @@ -1672,7 +1675,8 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N, | |||||||
|        << ".Val)) goto P" << PatternNo << "Fail;\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) { | static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) { | ||||||
|   const std::vector<CodeGenRegisterClass> &RegisterClasses = |   const std::vector<CodeGenRegisterClass> &RegisterClasses = | ||||||
|     T.getRegisterClasses(); |     T.getRegisterClasses(); | ||||||
| @@ -1681,7 +1685,7 @@ static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) { | |||||||
|     const CodeGenRegisterClass &RC = RegisterClasses[i]; |     const CodeGenRegisterClass &RC = RegisterClasses[i]; | ||||||
|     for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) { |     for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) { | ||||||
|       if (R == RC.Elements[ei]) { |       if (R == RC.Elements[ei]) { | ||||||
|         return RC.VT; |         return RC.getValueTypeNum(0); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -109,6 +109,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { | |||||||
|   // belongs to. |   // belongs to. | ||||||
|   std::multimap<Record*, const CodeGenRegisterClass*> RegClassesBelongedTo; |   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) { |   for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { | ||||||
|     const CodeGenRegisterClass &RC = RegisterClasses[rc]; |     const CodeGenRegisterClass &RC = RegisterClasses[rc]; | ||||||
|  |  | ||||||
| @@ -127,6 +128,22 @@ void RegisterInfoEmitter::run(std::ostream &OS) { | |||||||
|     } |     } | ||||||
|     OS << "\n  };\n\n"; |     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"; |   OS << "}  // end anonymous namespace\n\n"; | ||||||
|    |    | ||||||
|   // Now that all of the structs have been emitted, emit the instances. |   // Now that all of the structs have been emitted, emit the instances. | ||||||
| @@ -141,7 +158,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { | |||||||
|       const CodeGenRegisterClass &RC = RegisterClasses[i]; |       const CodeGenRegisterClass &RC = RegisterClasses[i]; | ||||||
|       OS << RC.MethodBodies << "\n"; |       OS << RC.MethodBodies << "\n"; | ||||||
|       OS << RC.getName() << "Class::" << RC.getName()  |       OS << RC.getName() << "Class::" << RC.getName()  | ||||||
|          << "Class()  : TargetRegisterClass(MVT::" << getEnumName(RC.VT) << "," |          << "Class()  : TargetRegisterClass(" << RC.getName() + "VTs" << ", " | ||||||
|          << RC.SpillSize/8 << ", " |          << RC.SpillSize/8 << ", " | ||||||
|          << RC.SpillAlignment/8 << ", " << RC.getName() << ", " |          << RC.SpillAlignment/8 << ", " << RC.getName() << ", " | ||||||
|          << RC.getName() << " + " << RC.Elements.size() << ") {}\n"; |          << RC.getName() << " + " << RC.Elements.size() << ") {}\n"; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user