diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 94430bc6cc0..b9ec987cd1a 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -125,9 +125,9 @@ class RegisterClass regTypes, int alignment, // list MemberList = regList; - // SubClassList - Specify which register classes correspond to subregisters - // of this class. The order should be by subregister set index. - list SubRegClassList = []; + // SubRegClasses - Specify the register class of subregisters as a list of + // dags: (RegClass SubRegIndex, SubRegindex, ...) + list SubRegClasses = []; // MethodProtos/MethodBodies - These members can be used to insert arbitrary // code into a generated register class. The normal usage of this is to diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index aeb669d6730..053168a2a9d 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -152,9 +152,6 @@ public: /// index SubIdx, or NULL if no such class exists. const TargetRegisterClass* getSubRegisterRegClass(unsigned SubIdx) const { assert(SubIdx>0 && "Invalid subregister index"); - for (unsigned s = 0; s != SubIdx-1; ++s) - if (!SubRegClasses[s]) - return NULL; return SubRegClasses[SubIdx-1]; } diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 8dab8cace38..fc86e3bc0bd 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -23,6 +23,32 @@ class ARMFReg num, string n> : Register { let Namespace = "ARM"; } +// Subregister indices. +let Namespace = "ARM" in { +// Note: Code depends on these having consecutive numbers. +def ssub_0 : SubRegIndex { let NumberHack = 1; } +def ssub_1 : SubRegIndex { let NumberHack = 2; } +def ssub_2 : SubRegIndex { let NumberHack = 3; } +def ssub_3 : SubRegIndex { let NumberHack = 4; } + +def dsub_0 : SubRegIndex { let NumberHack = 5; } +def dsub_1 : SubRegIndex { let NumberHack = 6; } +def dsub_2 : SubRegIndex { let NumberHack = 7; } +def dsub_3 : SubRegIndex { let NumberHack = 8; } +def dsub_4 : SubRegIndex { let NumberHack = 9; } +def dsub_5 : SubRegIndex { let NumberHack = 10; } +def dsub_6 : SubRegIndex { let NumberHack = 11; } +def dsub_7 : SubRegIndex { let NumberHack = 12; } + +def qsub_0 : SubRegIndex { let NumberHack = 13; } +def qsub_1 : SubRegIndex { let NumberHack = 14; } +def qsub_2 : SubRegIndex { let NumberHack = 15; } +def qsub_3 : SubRegIndex { let NumberHack = 16; } + +def qqsub_0 : SubRegIndex { let NumberHack = 17; } +def qqsub_1 : SubRegIndex { let NumberHack = 18; } +} + // Integer registers def R0 : ARMReg< 0, "r0">, DwarfRegNum<[0]>; def R1 : ARMReg< 1, "r1">, DwarfRegNum<[1]>; @@ -308,7 +334,6 @@ def DPR : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31]> { - let SubRegClassList = [SPR_INVALID, SPR_INVALID]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -356,14 +381,14 @@ def DPR : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, def DPR_VFP2 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15]> { - let SubRegClassList = [SPR, SPR]; + let SubRegClasses = [(SPR ssub_0, ssub_1)]; } // Subset of DPR which can be used as a source of NEON scalars for 16-bit // operations def DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, [D0, D1, D2, D3, D4, D5, D6, D7]> { - let SubRegClassList = [SPR_8, SPR_8]; + let SubRegClasses = [(SPR_8 ssub_0, ssub_1)]; } // Dummy 64-bit regclass to represent impossible subreg indices. @@ -377,27 +402,23 @@ def DPR_INVALID : RegisterClass<"ARM", def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15]> { - let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID, - DPR, DPR, DPR_INVALID, DPR_INVALID, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; + let SubRegClasses = [(DPR dsub_0, dsub_1)]; } // Subset of QPR that have 32-bit SPR subregs. def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]> { - let SubRegClassList = [SPR, SPR, SPR, SPR, - DPR_VFP2, DPR_VFP2, DPR_INVALID, DPR_INVALID, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; + let SubRegClasses = [(SPR ssub_0, ssub_1, ssub_2, ssub_3), + (DPR_VFP2 dsub_0, dsub_1)]; } // Subset of QPR that have DPR_8 and SPR_8 subregs. def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3]> { - let SubRegClassList = [SPR_8, SPR_8, SPR_8, SPR_8, - DPR_8, DPR_8, DPR_INVALID, DPR_INVALID, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; + let SubRegClasses = [(SPR_8 ssub_0, ssub_1, ssub_2, ssub_3), + (DPR_8 dsub_0, dsub_1)]; } // Dummy 128-bit regclass to represent impossible subreg indices. @@ -412,20 +433,18 @@ def QPR_INVALID : RegisterClass<"ARM", def QQPR : RegisterClass<"ARM", [v4i64], 256, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7]> { - let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID, - DPR, DPR, DPR, DPR, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID, - QPR, QPR, QPR_INVALID, QPR_INVALID]; + let SubRegClasses = [(DPR dsub_0, dsub_1, dsub_2, dsub_3), + (QPR qsub_0, qsub_1)]; } // Subset of QQPR that have 32-bit SPR subregs. def QQPR_VFP2 : RegisterClass<"ARM", [v4i64], 256, [QQ0, QQ1, QQ2, QQ3]> { - let SubRegClassList = [SPR, SPR, SPR, SPR, - DPR_VFP2, DPR_VFP2, DPR_VFP2, DPR_VFP2, - DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID, - QPR_VFP2, QPR_VFP2, QPR_INVALID, QPR_INVALID]; + let SubRegClasses = [(SPR ssub_0, ssub_1, ssub_2, ssub_3), + (DPR_VFP2 dsub_0, dsub_1, dsub_2, dsub_3), + (QPR_VFP2 qsub_0, qsub_1)]; + } // Pseudo 512-bit vector register class to model 4 consecutive Q registers @@ -433,9 +452,9 @@ def QQPR_VFP2 : RegisterClass<"ARM", [v4i64], def QQQQPR : RegisterClass<"ARM", [v8i64], 256, [QQQQ0, QQQQ1, QQQQ2, QQQQ3]> { - let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID, - DPR, DPR, DPR, DPR, DPR, DPR, DPR, DPR, - QPR, QPR, QPR, QPR]; + let SubRegClasses = [(DPR dsub_0, dsub_1, dsub_2, dsub_3, + dsub_4, dsub_5, dsub_6, dsub_7), + (QPR qsub_0, qsub_1, qsub_2, qsub_3)]; } // Condition code registers. @@ -445,30 +464,6 @@ def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>; // Subregister Set Definitions... now that we have all of the pieces, define the // sub registers for each register. // -let Namespace = "ARM" in { -// Note: Code depends on these having consecutive numbers. -def ssub_0 : SubRegIndex { let NumberHack = 1; } -def ssub_1 : SubRegIndex { let NumberHack = 2; } -def ssub_2 : SubRegIndex { let NumberHack = 3; } -def ssub_3 : SubRegIndex { let NumberHack = 4; } - -def dsub_0 : SubRegIndex { let NumberHack = 5; } -def dsub_1 : SubRegIndex { let NumberHack = 6; } -def dsub_2 : SubRegIndex { let NumberHack = 7; } -def dsub_3 : SubRegIndex { let NumberHack = 8; } -def dsub_4 : SubRegIndex { let NumberHack = 9; } -def dsub_5 : SubRegIndex { let NumberHack = 10; } -def dsub_6 : SubRegIndex { let NumberHack = 11; } -def dsub_7 : SubRegIndex { let NumberHack = 12; } - -def qsub_0 : SubRegIndex { let NumberHack = 13; } -def qsub_1 : SubRegIndex { let NumberHack = 14; } -def qsub_2 : SubRegIndex { let NumberHack = 15; } -def qsub_3 : SubRegIndex { let NumberHack = 16; } - -def qqsub_0 : SubRegIndex { let NumberHack = 17; } -def qqsub_1 : SubRegIndex { let NumberHack = 18; } -} // S sub-registers of D registers. def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7, diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.td b/lib/Target/Blackfin/BlackfinRegisterInfo.td index 2a7336c5b91..09c5d754e4e 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.td +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.td @@ -260,11 +260,11 @@ def GR16 : RegisterClass<"BF", [i16], 16, L0H, L0L, L1H, L1L, L2H, L2L, L3H, L3L]>; def D : RegisterClass<"BF", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7]> { - let SubRegClassList = [D16L, D16H]; + let SubRegClasses = [(D16L lo16), (D16H hi16)]; } def P : RegisterClass<"BF", [i32], 32, [P0, P1, P2, P3, P4, P5, FP, SP]> { - let SubRegClassList = [P16L, P16H]; + let SubRegClasses = [(P16L lo16), (P16H hi16)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -287,7 +287,7 @@ def L : RegisterClass<"BF", [i32], 32, [L0, L1, L2, L3]>; def DP : RegisterClass<"BF", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7, P0, P1, P2, P3, P4, P5, FP, SP]> { - let SubRegClassList = [DP16L, DP16H]; + let SubRegClasses = [(DP16L lo16), (DP16H hi16)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; diff --git a/lib/Target/MSP430/MSP430RegisterInfo.td b/lib/Target/MSP430/MSP430RegisterInfo.td index db3f0e789ab..bacc1c0506f 100644 --- a/lib/Target/MSP430/MSP430RegisterInfo.td +++ b/lib/Target/MSP430/MSP430RegisterInfo.td @@ -104,7 +104,7 @@ def GR16 : RegisterClass<"MSP430", [i16], 16, // Volatile, but not allocable PCW, SPW, SRW, CGW]> { - let SubRegClassList = [GR8]; + let SubRegClasses = [(GR8 subreg_8bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index 79570042f69..b024ecd1fbc 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -257,7 +257,7 @@ def AFGR64 : RegisterClass<"Mips", [f64], 64, // Reserved D15]> { - let SubRegClassList = [FGR32, FGR32]; + let SubRegClasses = [(FGR32 sub_fpeven, sub_fpodd)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; diff --git a/lib/Target/PowerPC/PPCRegisterInfo.td b/lib/Target/PowerPC/PPCRegisterInfo.td index 4596ad0116b..632ae196691 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/lib/Target/PowerPC/PPCRegisterInfo.td @@ -379,7 +379,7 @@ def CRBITRC : RegisterClass<"PPC", [i32], 32, def CRRC : RegisterClass<"PPC", [i32], 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]> { - let SubRegClassList = [CRBITRC, CRBITRC, CRBITRC, CRBITRC]; + let SubRegClasses = [(CRBITRC sub_lt, sub_gt, sub_eq, sub_un)]; } def CTRRC : RegisterClass<"PPC", [i32], 32, [CTR]>; diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.td b/lib/Target/SystemZ/SystemZRegisterInfo.td index 1690ea847a9..6b9924dca27 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.td +++ b/lib/Target/SystemZ/SystemZRegisterInfo.td @@ -278,7 +278,7 @@ def GR64 : RegisterClass<"SystemZ", [i64], 64, // Volatile, but not allocable R14D, R15D]> { - let SubRegClassList = [GR32]; + let SubRegClasses = [(GR32 subreg_32bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -325,7 +325,7 @@ def ADDR64 : RegisterClass<"SystemZ", [i64], 64, // Volatile, but not allocable R14D, R15D]> { - let SubRegClassList = [ADDR32]; + let SubRegClasses = [(ADDR32 subreg_32bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -368,7 +368,7 @@ def ADDR64 : RegisterClass<"SystemZ", [i64], 64, def GR64P : RegisterClass<"SystemZ", [v2i32], 64, [R0P, R2P, R4P, R6P, R8P, R10P, R12P, R14P]> { - let SubRegClassList = [GR32, GR32]; + let SubRegClasses = [(GR32 subreg_even32, subreg_odd32)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -404,7 +404,8 @@ def GR64P : RegisterClass<"SystemZ", [v2i32], 64, def GR128 : RegisterClass<"SystemZ", [v2i64], 128, [R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q]> { - let SubRegClassList = [GR32, GR32, GR64, GR64]; + let SubRegClasses = [(GR32 subreg_even32, subreg_odd32), + (GR64 subreg_even, subreg_odd)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -464,7 +465,7 @@ def FP32 : RegisterClass<"SystemZ", [f32], 32, def FP64 : RegisterClass<"SystemZ", [f64], 64, [F0L, F1L, F2L, F3L, F4L, F5L, F6L, F7L, F8L, F9L, F10L, F11L, F12L, F13L, F14L, F15L]> { - let SubRegClassList = [FP32]; + let SubRegClasses = [(FP32 subreg_32bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index 83c38c96a50..ac2c9a4592c 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -363,7 +363,7 @@ def GR8 : RegisterClass<"X86", [i8], 8, def GR16 : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP, R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> { - let SubRegClassList = [GR8, GR8]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -415,7 +415,7 @@ def GR16 : RegisterClass<"X86", [i16], 16, def GR32 : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { - let SubRegClassList = [GR8, GR8, GR16]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -470,7 +470,9 @@ def GR32 : RegisterClass<"X86", [i32], 32, def GR64 : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, RBX, R14, R15, R12, R13, RBP, RSP, RIP]> { - let SubRegClassList = [GR8, GR8, GR16, GR32]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), + (GR16 sub_16bit), + (GR32 sub_32bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -519,20 +521,27 @@ def GR8_ABCD_L : RegisterClass<"X86", [i8], 8, [AL, CL, DL, BL]> { def GR8_ABCD_H : RegisterClass<"X86", [i8], 8, [AH, CH, DH, BH]> { } def GR16_ABCD : RegisterClass<"X86", [i16], 16, [AX, CX, DX, BX]> { - let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H]; + let SubRegClasses = [(GR8_ABCD_L sub_8bit), (GR8_ABCD_H sub_8bit_hi)]; } def GR32_ABCD : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]> { - let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD]; + let SubRegClasses = [(GR8_ABCD_L sub_8bit), + (GR8_ABCD_H sub_8bit_hi), + (GR16_ABCD sub_16bit)]; } def GR64_ABCD : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RBX]> { - let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD, GR32_ABCD]; + let SubRegClasses = [(GR8_ABCD_L sub_8bit), + (GR8_ABCD_H sub_8bit_hi), + (GR16_ABCD sub_16bit), + (GR32_ABCD sub_32bit)]; } def GR32_TC : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX]> { - let SubRegClassList = [GR8, GR8, GR16]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)]; } def GR64_TC : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R11]> { - let SubRegClassList = [GR8, GR8, GR16, GR32_TC]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), + (GR16 sub_16bit), + (GR32_TC sub_32bit)]; } // GR8_NOREX - GR8 registers which do not require a REX prefix. @@ -572,7 +581,7 @@ def GR8_NOREX : RegisterClass<"X86", [i8], 8, // GR16_NOREX - GR16 registers which do not require a REX prefix. def GR16_NOREX : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP]> { - let SubRegClassList = [GR8_NOREX, GR8_NOREX]; + let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -595,7 +604,8 @@ def GR16_NOREX : RegisterClass<"X86", [i16], 16, // GR32_NOREX - GR32 registers which do not require a REX prefix. def GR32_NOREX : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> { - let SubRegClassList = [GR8_NOREX, GR8_NOREX, GR16_NOREX]; + let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi), + (GR16_NOREX sub_16bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -618,7 +628,9 @@ def GR32_NOREX : RegisterClass<"X86", [i32], 32, // GR64_NOREX - GR64 registers which do not require a REX prefix. def GR64_NOREX : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, RBX, RBP, RSP, RIP]> { - let SubRegClassList = [GR8_NOREX, GR8_NOREX, GR16_NOREX, GR32_NOREX]; + let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi), + (GR16_NOREX sub_16bit), + (GR32_NOREX sub_32bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -643,7 +655,7 @@ def GR64_NOREX : RegisterClass<"X86", [i64], 64, def GR32_NOSP : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { - let SubRegClassList = [GR8, GR8, GR16]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -696,7 +708,9 @@ def GR32_NOSP : RegisterClass<"X86", [i32], 32, def GR64_NOSP : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, RBX, R14, R15, R12, R13, RBP]> { - let SubRegClassList = [GR8, GR8, GR16, GR32_NOSP]; + let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), + (GR16 sub_16bit), + (GR32_NOSP sub_32bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -721,7 +735,9 @@ def GR64_NOSP : RegisterClass<"X86", [i64], 64, // GR64_NOREX_NOSP - GR64_NOREX registers except RSP. def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI, RBX, RBP]> { - let SubRegClassList = [GR8_NOREX, GR8_NOREX, GR16_NOREX, GR32_NOREX]; + let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi), + (GR16_NOREX sub_16bit), + (GR32_NOREX sub_32bit)]; let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -745,7 +761,9 @@ def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64, // A class to support the 'A' assembler constraint: EAX then EDX. def GR32_AD : RegisterClass<"X86", [i32], 32, [EAX, EDX]> { - let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD]; + let SubRegClasses = [(GR8_ABCD_L sub_8bit), + (GR8_ABCD_H sub_8bit_hi), + (GR16_ABCD sub_16bit)]; } // Scalar SSE2 floating point registers. @@ -823,7 +841,8 @@ def VR128 : RegisterClass<"X86", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],128, [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15]> { - let SubRegClassList = [FR32, FR64]; + let SubRegClasses = [(FR32 sub_ss), (FR64 sub_sd)]; + let MethodProtos = [{ iterator allocation_order_end(const MachineFunction &MF) const; }]; @@ -843,7 +862,7 @@ def VR256 : RegisterClass<"X86", [ v8i32, v4i64, v8f32, v4f64],256, [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15]> { - let SubRegClassList = [FR32, FR64, VR128]; + let SubRegClasses = [(FR32 sub_ss), (FR64 sub_sd), (VR128 sub_xmm)]; } // Status flags registers. diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 6f8682be59d..344f77f1fed 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -16,6 +16,7 @@ #define CODEGEN_REGISTERS_H #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/ADT/DenseMap.h" #include #include #include @@ -40,7 +41,8 @@ namespace llvm { unsigned SpillSize; unsigned SpillAlignment; int CopyCost; - std::vector SubRegClasses; + // Map SubRegIndex -> RegisterClass + DenseMap SubRegClasses; std::string MethodProtos, MethodBodies; const std::string &getName() const; diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index f13f969dd35..5d454892301 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -173,6 +173,10 @@ const std::string &CodeGenRegister::getName() const { return TheDef->getName(); } +void CodeGenTarget::ReadSubRegIndices() const { + SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex"); +} + void CodeGenTarget::ReadRegisterClasses() const { std::vector RegClasses = Records.getAllDerivedDefinitions("RegisterClass"); @@ -229,17 +233,30 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) { "' does not derive from the Register class!"; Elements.push_back(Reg); } - - std::vector SubRegClassList = - R->getValueAsListOfDefs("SubRegClassList"); - for (unsigned i = 0, e = SubRegClassList.size(); i != e; ++i) { - Record *SubRegClass = SubRegClassList[i]; - if (!SubRegClass->isSubClassOf("RegisterClass")) - throw "Register Class member '" + SubRegClass->getName() + - "' does not derive from the RegisterClass class!"; - SubRegClasses.push_back(SubRegClass); - } - + + // SubRegClasses is a list containing (RC, subregindex, ...) dags. + ListInit *SRC = R->getValueAsListInit("SubRegClasses"); + for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) { + DagInit *DAG = dynamic_cast(*i); + if (!DAG) throw "SubRegClasses must contain DAGs"; + DefInit *DAGOp = dynamic_cast(DAG->getOperator()); + Record *RCRec; + if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass")) + throw "Operator '" + DAG->getOperator()->getAsString() + + "' in SubRegClasses is not a RegisterClass"; + // Iterate over args, all SubRegIndex instances. + for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end(); + ai != ae; ++ai) { + DefInit *Idx = dynamic_cast(*ai); + Record *IdxRec; + if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex")) + throw "Argument '" + (*ai)->getAsString() + + "' in SubRegClasses is not a SubRegIndex"; + if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second) + throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice"; + } + } + // Allow targets to override the size in bits of the RegisterClass. unsigned Size = R->getValueAsInt("Size"); diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 29264189b74..5b2587f3b7f 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -19,14 +19,12 @@ #include "CodeGenRegisters.h" #include "CodeGenInstruction.h" +#include "Record.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/DenseMap.h" #include namespace llvm { -class Record; -class RecordKeeper; struct CodeGenRegister; class CodeGenTarget; @@ -65,9 +63,11 @@ class CodeGenTarget { mutable DenseMap Instructions; mutable std::vector Registers; + mutable std::vector SubRegIndices; mutable std::vector RegisterClasses; mutable std::vector LegalValueTypes; void ReadRegisters() const; + void ReadSubRegIndices() const; void ReadRegisterClasses() const; void ReadInstructions() const; void ReadLegalValueTypes() const; @@ -100,11 +100,21 @@ public: return Registers; } + const std::vector &getSubRegIndices() const { + if (SubRegIndices.empty()) ReadSubRegIndices(); + return SubRegIndices; + } + + // Map a SubRegIndex Record to its number. + unsigned getSubRegIndexNo(Record *idx) const { + return idx->getValueAsInt("NumberHack"); + } + const std::vector &getRegisterClasses() const { if (RegisterClasses.empty()) ReadRegisterClasses(); return RegisterClasses; } - + const CodeGenRegisterClass &getRegisterClass(Record *R) const { const std::vector &RC = getRegisterClasses(); for (unsigned i = 0, e = RC.size(); i != e; ++i) diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index a5fabeab5a0..0b0bf0e102d 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -44,8 +44,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) { if (!Namespace.empty()) OS << "}\n"; - const std::vector SubRegIndices = - Records.getAllDerivedDefinitions("SubRegIndex"); + const std::vector SubRegIndices = Target.getSubRegIndices(); if (!SubRegIndices.empty()) { OS << "\n// Subregister indices\n"; Namespace = SubRegIndices[0]->getValueAsString("Namespace"); @@ -260,80 +259,82 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { std::map > SuperRegClassMap; OS << "\n"; - // Emit the sub-register classes for each RegisterClass - for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; + unsigned NumSubRegIndices = Target.getSubRegIndices().size(); - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); + if (NumSubRegIndices) { + // Emit the sub-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + std::vector SRC(NumSubRegIndices); + for (DenseMap::const_iterator + i = RC.SubRegClasses.begin(), + e = RC.SubRegClasses.end(); i != e; ++i) { + // Build SRC array. + unsigned idx = Target.getSubRegIndexNo(i->first); + SRC.at(idx-1) = i->second; - OS << " // " << Name - << " Sub-register Classes...\n" - << " static const TargetRegisterClass* const " - << Name << "SubRegClasses[] = {\n "; + // Find the register class number of i->second for SuperRegClassMap. + for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) { + const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; + if (RC2.TheDef == i->second) { + SuperRegClassMap[rc2].insert(rc); + break; + } + } + } - bool Empty = true; + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); - for (unsigned subrc = 0, subrcMax = RC.SubRegClasses.size(); - subrc != subrcMax; ++subrc) { - unsigned rc2 = 0, e2 = RegisterClasses.size(); - for (; rc2 != e2; ++rc2) { - const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; - if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) { + OS << " // " << Name + << " Sub-register Classes...\n" + << " static const TargetRegisterClass* const " + << Name << "SubRegClasses[] = {\n "; + + for (unsigned idx = 0; idx != NumSubRegIndices; ++idx) { + if (idx) + OS << ", "; + if (SRC[idx]) + OS << "&" << getQualifiedName(SRC[idx]) << "RegClass"; + else + OS << "0"; + } + OS << "\n };\n\n"; + } + + // Emit the super-register classes 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(); + + OS << " // " << Name + << " Super-register Classes...\n" + << " static const TargetRegisterClass* const " + << Name << "SuperRegClasses[] = {\n "; + + bool Empty = true; + std::map >::iterator I = + SuperRegClassMap.find(rc); + if (I != SuperRegClassMap.end()) { + for (std::set::iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) { + const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; if (!Empty) OS << ", "; OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; Empty = false; - - std::map >::iterator SCMI = - SuperRegClassMap.find(rc2); - if (SCMI == SuperRegClassMap.end()) { - SuperRegClassMap.insert(std::make_pair(rc2, - std::set())); - SCMI = SuperRegClassMap.find(rc2); - } - SCMI->second.insert(rc); - break; } } - if (rc2 == e2) - throw "Register Class member '" + - RC.SubRegClasses[subrc]->getName() + - "' is not a valid RegisterClass!"; + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; - } - - // Emit the super-register classes 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(); - - OS << " // " << Name - << " Super-register Classes...\n" - << " static const TargetRegisterClass* const " - << Name << "SuperRegClasses[] = {\n "; - - bool Empty = true; - std::map >::iterator I = - SuperRegClassMap.find(rc); - if (I != SuperRegClassMap.end()) { - for (std::set::iterator II = I->second.begin(), - EE = I->second.end(); II != EE; ++II) { - const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; - if (!Empty) - OS << ", "; - OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; - Empty = false; - } - } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; + } else { + // No subregindices in this target + OS << " static const TargetRegisterClass* const " + << "NullRegClasses[] = { NULL };\n\n"; } // Emit the sub-classes array for each RegisterClass @@ -430,8 +431,10 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " << RC.getName() + "Superclasses" << ", " - << RC.getName() + "SubRegClasses" << ", " - << RC.getName() + "SuperRegClasses" << ", " + << (NumSubRegIndices ? RC.getName() + "Sub" : std::string("Null")) + << "RegClasses, " + << (NumSubRegIndices ? RC.getName() + "Super" : std::string("Null")) + << "RegClasses, " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.CopyCost << ", "