mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-10 13:51:37 +00:00
Replace the tablegen RegisterClass field SubRegClassList with an alist-like data
structure that represents a mapping without any dependencies on SubRegIndex numbering. This brings us closer to being able to remove the explicit SubRegIndex numbering, and it is now possible to specify any mapping without inventing *_INVALID register classes. llvm-svn: 104563
This commit is contained in:
parent
e34814c0bc
commit
3a19b732d8
@ -125,9 +125,9 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
|
|||||||
//
|
//
|
||||||
list<Register> MemberList = regList;
|
list<Register> MemberList = regList;
|
||||||
|
|
||||||
// SubClassList - Specify which register classes correspond to subregisters
|
// SubRegClasses - Specify the register class of subregisters as a list of
|
||||||
// of this class. The order should be by subregister set index.
|
// dags: (RegClass SubRegIndex, SubRegindex, ...)
|
||||||
list<RegisterClass> SubRegClassList = [];
|
list<dag> SubRegClasses = [];
|
||||||
|
|
||||||
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
|
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
|
||||||
// code into a generated register class. The normal usage of this is to
|
// code into a generated register class. The normal usage of this is to
|
||||||
|
@ -152,9 +152,6 @@ public:
|
|||||||
/// index SubIdx, or NULL if no such class exists.
|
/// index SubIdx, or NULL if no such class exists.
|
||||||
const TargetRegisterClass* getSubRegisterRegClass(unsigned SubIdx) const {
|
const TargetRegisterClass* getSubRegisterRegClass(unsigned SubIdx) const {
|
||||||
assert(SubIdx>0 && "Invalid subregister index");
|
assert(SubIdx>0 && "Invalid subregister index");
|
||||||
for (unsigned s = 0; s != SubIdx-1; ++s)
|
|
||||||
if (!SubRegClasses[s])
|
|
||||||
return NULL;
|
|
||||||
return SubRegClasses[SubIdx-1];
|
return SubRegClasses[SubIdx-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,32 @@ class ARMFReg<bits<6> num, string n> : Register<n> {
|
|||||||
let Namespace = "ARM";
|
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
|
// Integer registers
|
||||||
def R0 : ARMReg< 0, "r0">, DwarfRegNum<[0]>;
|
def R0 : ARMReg< 0, "r0">, DwarfRegNum<[0]>;
|
||||||
def R1 : ARMReg< 1, "r1">, DwarfRegNum<[1]>;
|
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,
|
D8, D9, D10, D11, D12, D13, D14, D15,
|
||||||
D16, D17, D18, D19, D20, D21, D22, D23,
|
D16, D17, D18, D19, D20, D21, D22, D23,
|
||||||
D24, D25, D26, D27, D28, D29, D30, D31]> {
|
D24, D25, D26, D27, D28, D29, D30, D31]> {
|
||||||
let SubRegClassList = [SPR_INVALID, SPR_INVALID];
|
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(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,
|
def DPR_VFP2 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64,
|
||||||
[D0, D1, D2, D3, D4, D5, D6, D7,
|
[D0, D1, D2, D3, D4, D5, D6, D7,
|
||||||
D8, D9, D10, D11, D12, D13, D14, D15]> {
|
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
|
// Subset of DPR which can be used as a source of NEON scalars for 16-bit
|
||||||
// operations
|
// operations
|
||||||
def DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64,
|
def DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64,
|
||||||
[D0, D1, D2, D3, D4, D5, D6, D7]> {
|
[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.
|
// 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,
|
def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128,
|
||||||
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7,
|
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7,
|
||||||
Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15]> {
|
Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15]> {
|
||||||
let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID,
|
let SubRegClasses = [(DPR dsub_0, dsub_1)];
|
||||||
DPR, DPR, DPR_INVALID, DPR_INVALID,
|
|
||||||
DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subset of QPR that have 32-bit SPR subregs.
|
// Subset of QPR that have 32-bit SPR subregs.
|
||||||
def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
|
def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
|
||||||
128,
|
128,
|
||||||
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]> {
|
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]> {
|
||||||
let SubRegClassList = [SPR, SPR, SPR, SPR,
|
let SubRegClasses = [(SPR ssub_0, ssub_1, ssub_2, ssub_3),
|
||||||
DPR_VFP2, DPR_VFP2, DPR_INVALID, DPR_INVALID,
|
(DPR_VFP2 dsub_0, dsub_1)];
|
||||||
DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subset of QPR that have DPR_8 and SPR_8 subregs.
|
// Subset of QPR that have DPR_8 and SPR_8 subregs.
|
||||||
def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
|
def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
|
||||||
128,
|
128,
|
||||||
[Q0, Q1, Q2, Q3]> {
|
[Q0, Q1, Q2, Q3]> {
|
||||||
let SubRegClassList = [SPR_8, SPR_8, SPR_8, SPR_8,
|
let SubRegClasses = [(SPR_8 ssub_0, ssub_1, ssub_2, ssub_3),
|
||||||
DPR_8, DPR_8, DPR_INVALID, DPR_INVALID,
|
(DPR_8 dsub_0, dsub_1)];
|
||||||
DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dummy 128-bit regclass to represent impossible subreg indices.
|
// Dummy 128-bit regclass to represent impossible subreg indices.
|
||||||
@ -412,20 +433,18 @@ def QPR_INVALID : RegisterClass<"ARM",
|
|||||||
def QQPR : RegisterClass<"ARM", [v4i64],
|
def QQPR : RegisterClass<"ARM", [v4i64],
|
||||||
256,
|
256,
|
||||||
[QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7]> {
|
[QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7]> {
|
||||||
let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID,
|
let SubRegClasses = [(DPR dsub_0, dsub_1, dsub_2, dsub_3),
|
||||||
DPR, DPR, DPR, DPR,
|
(QPR qsub_0, qsub_1)];
|
||||||
DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID,
|
|
||||||
QPR, QPR, QPR_INVALID, QPR_INVALID];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subset of QQPR that have 32-bit SPR subregs.
|
// Subset of QQPR that have 32-bit SPR subregs.
|
||||||
def QQPR_VFP2 : RegisterClass<"ARM", [v4i64],
|
def QQPR_VFP2 : RegisterClass<"ARM", [v4i64],
|
||||||
256,
|
256,
|
||||||
[QQ0, QQ1, QQ2, QQ3]> {
|
[QQ0, QQ1, QQ2, QQ3]> {
|
||||||
let SubRegClassList = [SPR, SPR, SPR, SPR,
|
let SubRegClasses = [(SPR ssub_0, ssub_1, ssub_2, ssub_3),
|
||||||
DPR_VFP2, DPR_VFP2, DPR_VFP2, DPR_VFP2,
|
(DPR_VFP2 dsub_0, dsub_1, dsub_2, dsub_3),
|
||||||
DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID,
|
(QPR_VFP2 qsub_0, qsub_1)];
|
||||||
QPR_VFP2, QPR_VFP2, QPR_INVALID, QPR_INVALID];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pseudo 512-bit vector register class to model 4 consecutive Q registers
|
// 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],
|
def QQQQPR : RegisterClass<"ARM", [v8i64],
|
||||||
256,
|
256,
|
||||||
[QQQQ0, QQQQ1, QQQQ2, QQQQ3]> {
|
[QQQQ0, QQQQ1, QQQQ2, QQQQ3]> {
|
||||||
let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID,
|
let SubRegClasses = [(DPR dsub_0, dsub_1, dsub_2, dsub_3,
|
||||||
DPR, DPR, DPR, DPR, DPR, DPR, DPR, DPR,
|
dsub_4, dsub_5, dsub_6, dsub_7),
|
||||||
QPR, QPR, QPR, QPR];
|
(QPR qsub_0, qsub_1, qsub_2, qsub_3)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Condition code registers.
|
// 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
|
// Subregister Set Definitions... now that we have all of the pieces, define the
|
||||||
// sub registers for each register.
|
// 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.
|
// S sub-registers of D registers.
|
||||||
def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7,
|
def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7,
|
||||||
|
@ -260,11 +260,11 @@ def GR16 : RegisterClass<"BF", [i16], 16,
|
|||||||
L0H, L0L, L1H, L1L, L2H, L2L, L3H, L3L]>;
|
L0H, L0L, L1H, L1L, L2H, L2L, L3H, L3L]>;
|
||||||
|
|
||||||
def D : RegisterClass<"BF", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7]> {
|
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]> {
|
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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
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,
|
def DP : RegisterClass<"BF", [i32], 32,
|
||||||
[R0, R1, R2, R3, R4, R5, R6, R7,
|
[R0, R1, R2, R3, R4, R5, R6, R7,
|
||||||
P0, P1, P2, P3, P4, P5, FP, SP]> {
|
P0, P1, P2, P3, P4, P5, FP, SP]> {
|
||||||
let SubRegClassList = [DP16L, DP16H];
|
let SubRegClasses = [(DP16L lo16), (DP16H hi16)];
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
iterator allocation_order_end(const MachineFunction &MF) const;
|
||||||
}];
|
}];
|
||||||
|
@ -104,7 +104,7 @@ def GR16 : RegisterClass<"MSP430", [i16], 16,
|
|||||||
// Volatile, but not allocable
|
// Volatile, but not allocable
|
||||||
PCW, SPW, SRW, CGW]>
|
PCW, SPW, SRW, CGW]>
|
||||||
{
|
{
|
||||||
let SubRegClassList = [GR8];
|
let SubRegClasses = [(GR8 subreg_8bit)];
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
iterator allocation_order_end(const MachineFunction &MF) const;
|
||||||
}];
|
}];
|
||||||
|
@ -257,7 +257,7 @@ def AFGR64 : RegisterClass<"Mips", [f64], 64,
|
|||||||
// Reserved
|
// Reserved
|
||||||
D15]>
|
D15]>
|
||||||
{
|
{
|
||||||
let SubRegClassList = [FGR32, FGR32];
|
let SubRegClasses = [(FGR32 sub_fpeven, sub_fpodd)];
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
iterator allocation_order_end(const MachineFunction &MF) const;
|
||||||
}];
|
}];
|
||||||
|
@ -379,7 +379,7 @@ def CRBITRC : RegisterClass<"PPC", [i32], 32,
|
|||||||
def CRRC : RegisterClass<"PPC", [i32], 32, [CR0, CR1, CR5, CR6, CR7, CR2,
|
def CRRC : RegisterClass<"PPC", [i32], 32, [CR0, CR1, CR5, CR6, CR7, CR2,
|
||||||
CR3, CR4]>
|
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]>;
|
def CTRRC : RegisterClass<"PPC", [i32], 32, [CTR]>;
|
||||||
|
@ -278,7 +278,7 @@ def GR64 : RegisterClass<"SystemZ", [i64], 64,
|
|||||||
// Volatile, but not allocable
|
// Volatile, but not allocable
|
||||||
R14D, R15D]>
|
R14D, R15D]>
|
||||||
{
|
{
|
||||||
let SubRegClassList = [GR32];
|
let SubRegClasses = [(GR32 subreg_32bit)];
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(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
|
// Volatile, but not allocable
|
||||||
R14D, R15D]>
|
R14D, R15D]>
|
||||||
{
|
{
|
||||||
let SubRegClassList = [ADDR32];
|
let SubRegClasses = [(ADDR32 subreg_32bit)];
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(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,
|
def GR64P : RegisterClass<"SystemZ", [v2i32], 64,
|
||||||
[R0P, R2P, R4P, R6P, R8P, R10P, R12P, R14P]>
|
[R0P, R2P, R4P, R6P, R8P, R10P, R12P, R14P]>
|
||||||
{
|
{
|
||||||
let SubRegClassList = [GR32, GR32];
|
let SubRegClasses = [(GR32 subreg_even32, subreg_odd32)];
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(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,
|
def GR128 : RegisterClass<"SystemZ", [v2i64], 128,
|
||||||
[R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q]>
|
[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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(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,
|
def FP64 : RegisterClass<"SystemZ", [f64], 64,
|
||||||
[F0L, F1L, F2L, F3L, F4L, F5L, F6L, F7L,
|
[F0L, F1L, F2L, F3L, F4L, F5L, F6L, F7L,
|
||||||
F8L, F9L, F10L, F11L, F12L, F13L, F14L, F15L]> {
|
F8L, F9L, F10L, F11L, F12L, F13L, F14L, F15L]> {
|
||||||
let SubRegClassList = [FP32];
|
let SubRegClasses = [(FP32 subreg_32bit)];
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
iterator allocation_order_end(const MachineFunction &MF) const;
|
||||||
|
@ -363,7 +363,7 @@ def GR8 : RegisterClass<"X86", [i8], 8,
|
|||||||
def GR16 : RegisterClass<"X86", [i16], 16,
|
def GR16 : RegisterClass<"X86", [i16], 16,
|
||||||
[AX, CX, DX, SI, DI, BX, BP, SP,
|
[AX, CX, DX, SI, DI, BX, BP, SP,
|
||||||
R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> {
|
R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> {
|
||||||
let SubRegClassList = [GR8, GR8];
|
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi)];
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(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,
|
def GR32 : RegisterClass<"X86", [i32], 32,
|
||||||
[EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP,
|
[EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP,
|
||||||
R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> {
|
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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(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,
|
def GR64 : RegisterClass<"X86", [i64], 64,
|
||||||
[RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
|
[RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
|
||||||
RBX, R14, R15, R12, R13, RBP, RSP, RIP]> {
|
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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
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 GR8_ABCD_H : RegisterClass<"X86", [i8], 8, [AH, CH, DH, BH]> {
|
||||||
}
|
}
|
||||||
def GR16_ABCD : RegisterClass<"X86", [i16], 16, [AX, CX, DX, BX]> {
|
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]> {
|
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]> {
|
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]> {
|
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,
|
def GR64_TC : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI,
|
||||||
R8, R9, R11]> {
|
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.
|
// 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.
|
// GR16_NOREX - GR16 registers which do not require a REX prefix.
|
||||||
def GR16_NOREX : RegisterClass<"X86", [i16], 16,
|
def GR16_NOREX : RegisterClass<"X86", [i16], 16,
|
||||||
[AX, CX, DX, SI, DI, BX, BP, SP]> {
|
[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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
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.
|
// GR32_NOREX - GR32 registers which do not require a REX prefix.
|
||||||
def GR32_NOREX : RegisterClass<"X86", [i32], 32,
|
def GR32_NOREX : RegisterClass<"X86", [i32], 32,
|
||||||
[EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> {
|
[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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
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.
|
// GR64_NOREX - GR64 registers which do not require a REX prefix.
|
||||||
def GR64_NOREX : RegisterClass<"X86", [i64], 64,
|
def GR64_NOREX : RegisterClass<"X86", [i64], 64,
|
||||||
[RAX, RCX, RDX, RSI, RDI, RBX, RBP, RSP, RIP]> {
|
[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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
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,
|
def GR32_NOSP : RegisterClass<"X86", [i32], 32,
|
||||||
[EAX, ECX, EDX, ESI, EDI, EBX, EBP,
|
[EAX, ECX, EDX, ESI, EDI, EBX, EBP,
|
||||||
R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> {
|
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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
iterator allocation_order_end(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,
|
def GR64_NOSP : RegisterClass<"X86", [i64], 64,
|
||||||
[RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
|
[RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
|
||||||
RBX, R14, R15, R12, R13, RBP]> {
|
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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
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.
|
// GR64_NOREX_NOSP - GR64_NOREX registers except RSP.
|
||||||
def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64,
|
def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64,
|
||||||
[RAX, RCX, RDX, RSI, RDI, RBX, RBP]> {
|
[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 = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
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.
|
// A class to support the 'A' assembler constraint: EAX then EDX.
|
||||||
def GR32_AD : RegisterClass<"X86", [i32], 32, [EAX, 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.
|
// 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,
|
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
||||||
XMM8, XMM9, XMM10, XMM11,
|
XMM8, XMM9, XMM10, XMM11,
|
||||||
XMM12, XMM13, XMM14, XMM15]> {
|
XMM12, XMM13, XMM14, XMM15]> {
|
||||||
let SubRegClassList = [FR32, FR64];
|
let SubRegClasses = [(FR32 sub_ss), (FR64 sub_sd)];
|
||||||
|
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(const MachineFunction &MF) const;
|
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,
|
[YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
|
||||||
YMM8, YMM9, YMM10, YMM11,
|
YMM8, YMM9, YMM10, YMM11,
|
||||||
YMM12, YMM13, YMM14, YMM15]> {
|
YMM12, YMM13, YMM14, YMM15]> {
|
||||||
let SubRegClassList = [FR32, FR64, VR128];
|
let SubRegClasses = [(FR32 sub_ss), (FR64 sub_sd), (VR128 sub_xmm)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status flags registers.
|
// Status flags registers.
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define CODEGEN_REGISTERS_H
|
#define CODEGEN_REGISTERS_H
|
||||||
|
|
||||||
#include "llvm/CodeGen/ValueTypes.h"
|
#include "llvm/CodeGen/ValueTypes.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -40,7 +41,8 @@ namespace llvm {
|
|||||||
unsigned SpillSize;
|
unsigned SpillSize;
|
||||||
unsigned SpillAlignment;
|
unsigned SpillAlignment;
|
||||||
int CopyCost;
|
int CopyCost;
|
||||||
std::vector<Record*> SubRegClasses;
|
// Map SubRegIndex -> RegisterClass
|
||||||
|
DenseMap<Record*,Record*> SubRegClasses;
|
||||||
std::string MethodProtos, MethodBodies;
|
std::string MethodProtos, MethodBodies;
|
||||||
|
|
||||||
const std::string &getName() const;
|
const std::string &getName() const;
|
||||||
|
@ -173,6 +173,10 @@ const std::string &CodeGenRegister::getName() const {
|
|||||||
return TheDef->getName();
|
return TheDef->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenTarget::ReadSubRegIndices() const {
|
||||||
|
SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex");
|
||||||
|
}
|
||||||
|
|
||||||
void CodeGenTarget::ReadRegisterClasses() const {
|
void CodeGenTarget::ReadRegisterClasses() const {
|
||||||
std::vector<Record*> RegClasses =
|
std::vector<Record*> RegClasses =
|
||||||
Records.getAllDerivedDefinitions("RegisterClass");
|
Records.getAllDerivedDefinitions("RegisterClass");
|
||||||
@ -229,17 +233,30 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Record*> SubRegClassList =
|
// SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags.
|
||||||
R->getValueAsListOfDefs("SubRegClassList");
|
ListInit *SRC = R->getValueAsListInit("SubRegClasses");
|
||||||
for (unsigned i = 0, e = SubRegClassList.size(); i != e; ++i) {
|
for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) {
|
||||||
Record *SubRegClass = SubRegClassList[i];
|
DagInit *DAG = dynamic_cast<DagInit*>(*i);
|
||||||
if (!SubRegClass->isSubClassOf("RegisterClass"))
|
if (!DAG) throw "SubRegClasses must contain DAGs";
|
||||||
throw "Register Class member '" + SubRegClass->getName() +
|
DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator());
|
||||||
"' does not derive from the RegisterClass class!";
|
Record *RCRec;
|
||||||
SubRegClasses.push_back(SubRegClass);
|
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.
|
// Allow targets to override the size in bits of the RegisterClass.
|
||||||
unsigned Size = R->getValueAsInt("Size");
|
unsigned Size = R->getValueAsInt("Size");
|
||||||
|
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
|
|
||||||
#include "CodeGenRegisters.h"
|
#include "CodeGenRegisters.h"
|
||||||
#include "CodeGenInstruction.h"
|
#include "CodeGenInstruction.h"
|
||||||
|
#include "Record.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class Record;
|
|
||||||
class RecordKeeper;
|
|
||||||
struct CodeGenRegister;
|
struct CodeGenRegister;
|
||||||
class CodeGenTarget;
|
class CodeGenTarget;
|
||||||
|
|
||||||
@ -65,9 +63,11 @@ class CodeGenTarget {
|
|||||||
|
|
||||||
mutable DenseMap<const Record*, CodeGenInstruction*> Instructions;
|
mutable DenseMap<const Record*, CodeGenInstruction*> Instructions;
|
||||||
mutable std::vector<CodeGenRegister> Registers;
|
mutable std::vector<CodeGenRegister> Registers;
|
||||||
|
mutable std::vector<Record*> SubRegIndices;
|
||||||
mutable std::vector<CodeGenRegisterClass> RegisterClasses;
|
mutable std::vector<CodeGenRegisterClass> RegisterClasses;
|
||||||
mutable std::vector<MVT::SimpleValueType> LegalValueTypes;
|
mutable std::vector<MVT::SimpleValueType> LegalValueTypes;
|
||||||
void ReadRegisters() const;
|
void ReadRegisters() const;
|
||||||
|
void ReadSubRegIndices() const;
|
||||||
void ReadRegisterClasses() const;
|
void ReadRegisterClasses() const;
|
||||||
void ReadInstructions() const;
|
void ReadInstructions() const;
|
||||||
void ReadLegalValueTypes() const;
|
void ReadLegalValueTypes() const;
|
||||||
@ -100,11 +100,21 @@ public:
|
|||||||
return Registers;
|
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 {
|
const std::vector<CodeGenRegisterClass> &getRegisterClasses() const {
|
||||||
if (RegisterClasses.empty()) ReadRegisterClasses();
|
if (RegisterClasses.empty()) ReadRegisterClasses();
|
||||||
return RegisterClasses;
|
return RegisterClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CodeGenRegisterClass &getRegisterClass(Record *R) const {
|
const CodeGenRegisterClass &getRegisterClass(Record *R) const {
|
||||||
const std::vector<CodeGenRegisterClass> &RC = getRegisterClasses();
|
const std::vector<CodeGenRegisterClass> &RC = getRegisterClasses();
|
||||||
for (unsigned i = 0, e = RC.size(); i != e; ++i)
|
for (unsigned i = 0, e = RC.size(); i != e; ++i)
|
||||||
|
@ -44,8 +44,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) {
|
|||||||
if (!Namespace.empty())
|
if (!Namespace.empty())
|
||||||
OS << "}\n";
|
OS << "}\n";
|
||||||
|
|
||||||
const std::vector<Record*> SubRegIndices =
|
const std::vector<Record*> SubRegIndices = Target.getSubRegIndices();
|
||||||
Records.getAllDerivedDefinitions("SubRegIndex");
|
|
||||||
if (!SubRegIndices.empty()) {
|
if (!SubRegIndices.empty()) {
|
||||||
OS << "\n// Subregister indices\n";
|
OS << "\n// Subregister indices\n";
|
||||||
Namespace = SubRegIndices[0]->getValueAsString("Namespace");
|
Namespace = SubRegIndices[0]->getValueAsString("Namespace");
|
||||||
@ -260,80 +259,82 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
|
|||||||
std::map<unsigned, std::set<unsigned> > SuperRegClassMap;
|
std::map<unsigned, std::set<unsigned> > SuperRegClassMap;
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
|
|
||||||
// Emit the sub-register classes for each RegisterClass
|
unsigned NumSubRegIndices = Target.getSubRegIndices().size();
|
||||||
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.
|
if (NumSubRegIndices) {
|
||||||
std::string Name = RC.TheDef->getName();
|
// 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;
|
||||||
|
|
||||||
OS << " // " << Name
|
// Find the register class number of i->second for SuperRegClassMap.
|
||||||
<< " Sub-register Classes...\n"
|
for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) {
|
||||||
<< " static const TargetRegisterClass* const "
|
const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
|
||||||
<< Name << "SubRegClasses[] = {\n ";
|
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();
|
OS << " // " << Name
|
||||||
subrc != subrcMax; ++subrc) {
|
<< " Sub-register Classes...\n"
|
||||||
unsigned rc2 = 0, e2 = RegisterClasses.size();
|
<< " static const TargetRegisterClass* const "
|
||||||
for (; rc2 != e2; ++rc2) {
|
<< Name << "SubRegClasses[] = {\n ";
|
||||||
const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
|
|
||||||
if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) {
|
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<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)
|
if (!Empty)
|
||||||
OS << ", ";
|
OS << ", ";
|
||||||
OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
|
OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
|
||||||
Empty = false;
|
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 '" +
|
OS << (!Empty ? ", " : "") << "NULL";
|
||||||
RC.SubRegClasses[subrc]->getName() +
|
OS << "\n };\n\n";
|
||||||
"' is not a valid RegisterClass!";
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
OS << (!Empty ? ", " : "") << "NULL";
|
// No subregindices in this target
|
||||||
OS << "\n };\n\n";
|
OS << " static const TargetRegisterClass* const "
|
||||||
}
|
<< "NullRegClasses[] = { NULL };\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";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit the sub-classes array for each RegisterClass
|
// Emit the sub-classes array for each RegisterClass
|
||||||
@ -430,8 +431,10 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
|
|||||||
<< RC.getName() + "VTs" << ", "
|
<< RC.getName() + "VTs" << ", "
|
||||||
<< RC.getName() + "Subclasses" << ", "
|
<< RC.getName() + "Subclasses" << ", "
|
||||||
<< RC.getName() + "Superclasses" << ", "
|
<< RC.getName() + "Superclasses" << ", "
|
||||||
<< RC.getName() + "SubRegClasses" << ", "
|
<< (NumSubRegIndices ? RC.getName() + "Sub" : std::string("Null"))
|
||||||
<< RC.getName() + "SuperRegClasses" << ", "
|
<< "RegClasses, "
|
||||||
|
<< (NumSubRegIndices ? RC.getName() + "Super" : std::string("Null"))
|
||||||
|
<< "RegClasses, "
|
||||||
<< RC.SpillSize/8 << ", "
|
<< RC.SpillSize/8 << ", "
|
||||||
<< RC.SpillAlignment/8 << ", "
|
<< RC.SpillAlignment/8 << ", "
|
||||||
<< RC.CopyCost << ", "
|
<< RC.CopyCost << ", "
|
||||||
|
Loading…
Reference in New Issue
Block a user