summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/Target.td6
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h3
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.td89
-rw-r--r--lib/Target/Blackfin/BlackfinRegisterInfo.td6
-rw-r--r--lib/Target/MSP430/MSP430RegisterInfo.td2
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td2
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.td2
-rw-r--r--lib/Target/SystemZ/SystemZRegisterInfo.td11
-rw-r--r--lib/Target/X86/X86RegisterInfo.td53
-rw-r--r--utils/TableGen/CodeGenRegisters.h4
-rw-r--r--utils/TableGen/CodeGenTarget.cpp39
-rw-r--r--utils/TableGen/CodeGenTarget.h18
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp135
13 files changed, 207 insertions, 163 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 94430bc6cc..b9ec987cd1 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -125,9 +125,9 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
//
list<Register> MemberList = regList;
- // SubClassList - Specify which register classes correspond to subregisters
- // of this class. The order should be by subregister set index.
- list<RegisterClass> SubRegClassList = [];
+ // SubRegClasses - Specify the register class of subregisters as a list of
+ // dags: (RegClass SubRegIndex, SubRegindex, ...)
+ list<dag> 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 aeb669d673..053168a2a9 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 8dab8cace3..fc86e3bc0b 100644
--- a/lib/Target/ARM/ARMRegisterInfo.td
+++ b/lib/Target/ARM/ARMRegisterInfo.td
@@ -23,6 +23,32 @@ class ARMFReg<bits<6> num, string n> : Register<n> {
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 2a7336c5b9..09c5d754e4 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 db3f0e789a..bacc1c0506 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 79570042f6..b024ecd1fb 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 4596ad0116..632ae19669 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 1690ea847a..6b9924dca2 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 83c38c96a5..ac2c9a4592 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 6f8682be59..344f77f1fe 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 <string>
#include <vector>
#include <cstdlib>
@@ -40,7 +41,8 @@ namespace llvm {
unsigned SpillSize;
unsigned SpillAlignment;
int CopyCost;
- std::vector<Record*> SubRegClasses;
+ // Map SubRegIndex -> RegisterClass
+ DenseMap<Record*,Record*> SubRegClasses;
std::string MethodProtos, MethodBodies;
const std::string &getName() const;
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index f13f969dd3..5d45489230 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<Record*> 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<Record*> 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<dag> 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<DagInit*>(*i);
+ if (!DAG) throw "SubRegClasses must contain DAGs";
+ DefInit *DAGOp = dynamic_cast<DefInit*>(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<DefInit*>(*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 29264189b7..5b2587f3b7 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 <algorithm>
namespace llvm {
-class Record;
-class RecordKeeper;
struct CodeGenRegister;
class CodeGenTarget;
@@ -65,9 +63,11 @@ class CodeGenTarget {
mutable DenseMap<const Record*, CodeGenInstruction*> Instructions;
mutable std::vector<CodeGenRegister> Registers;
+ mutable std::vector<Record*> SubRegIndices;
mutable std::vector<CodeGenRegisterClass> RegisterClasses;
mutable std::vector<MVT::SimpleValueType> 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<Record*> &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<CodeGenRegisterClass> &getRegisterClasses() const {
if (RegisterClasses.empty()) ReadRegisterClasses();
return RegisterClasses;
}
-
+
const CodeGenRegisterClass &getRegisterClass(Record *R) const {
const std::vector<CodeGenRegisterClass> &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 a5fabeab5a..0b0bf0e102 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<Record*> SubRegIndices =
- Records.getAllDerivedDefinitions("SubRegIndex");
+ const std::vector<Record*> 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<unsigned, std::set<unsigned> > 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();
+
+ 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<Record*> SRC(NumSubRegIndices);
+ for (DenseMap<Record*,Record*>::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;
+
+ // 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;
+ }
+ }
+ }
- // Give the register class a legal C name if it's anonymous.
- std::string Name = RC.TheDef->getName();
+ // Give the register class a legal C name if it's anonymous.
+ std::string Name = RC.TheDef->getName();
- OS << " // " << Name
- << " Sub-register Classes...\n"
- << " static const TargetRegisterClass* const "
- << Name << "SubRegClasses[] = {\n ";
+ OS << " // " << Name
+ << " Sub-register Classes...\n"
+ << " static const TargetRegisterClass* const "
+ << Name << "SubRegClasses[] = {\n ";
- bool Empty = true;
+ 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";
+ }
- 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()) {
+ // 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<unsigned, std::set<unsigned> >::iterator I =
+ SuperRegClassMap.find(rc);
+ if (I != SuperRegClassMap.end()) {
+ for (std::set<unsigned>::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<unsigned, std::set<unsigned> >::iterator SCMI =
- SuperRegClassMap.find(rc2);
- if (SCMI == SuperRegClassMap.end()) {
- SuperRegClassMap.insert(std::make_pair(rc2,
- std::set<unsigned>()));
- 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";
- }
-
- // 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<unsigned, std::set<unsigned> >::iterator I =
- SuperRegClassMap.find(rc);
- if (I != SuperRegClassMap.end()) {
- for (std::set<unsigned>::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";
}
-
- 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 << ", "