1 // RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK
2 include "llvm/Target/Target.td"
4 // This file tests that when using `isArtificial` for subregisters in
5 // combination with `CoveredBySubRegs`, that TableGen infers the
6 // correct register classes, subregisters and lane masks, especially
7 // when the registers (that consist partially from artificial subregs)
10 // The register hierarchy that this test implements is:
19 // Where the _hi parts are artificial and where subregs ssub, dsub and qsub
20 // are all addressable as real registers.
22 // These are then used in {S0, S1, S2}, {D0, D1, D2} and {Q0, Q1, Q2},
23 // from which tuples are created.
25 class MyReg<string n, list<Register> subregs = []>
27 let Namespace = "Test";
28 let SubRegs = subregs;
31 class MyClass<int size, list<ValueType> types, dag registers>
32 : RegisterClass<"Test", types, size, registers> {
36 def ssub : SubRegIndex< 32, 0>;
37 def ssub_hi : SubRegIndex< 32, 32>;
38 def dsub : SubRegIndex< 64, 0>;
39 def dsub_hi : SubRegIndex< 64, 64>;
40 def qsub : SubRegIndex<128, 0>;
46 let isArtificial = 1 in {
47 def S0_HI : MyReg<"s0_hi">;
48 def S1_HI : MyReg<"s1_hi">;
49 def S2_HI : MyReg<"s2_hi">;
51 def D0_HI : MyReg<"D0_hi">;
52 def D1_HI : MyReg<"D1_hi">;
53 def D2_HI : MyReg<"D2_hi">;
56 let SubRegIndices = [ssub, ssub_hi], CoveredBySubRegs = 1 in {
57 def D0 : MyReg<"d0", [S0, S0_HI]>;
58 def D1 : MyReg<"d1", [S1, S1_HI]>;
59 def D2 : MyReg<"d2", [S2, S2_HI]>;
62 let SubRegIndices = [dsub, dsub_hi], CoveredBySubRegs = 1 in {
63 def Q0 : MyReg<"q0", [D0, D0_HI]>;
64 def Q1 : MyReg<"q1", [D1, D1_HI]>;
65 def Q2 : MyReg<"q2", [D2, D2_HI]>;
68 def SRegs : MyClass<32, [i32], (sequence "S%u", 0, 2)>;
69 def DRegs : MyClass<64, [i64], (sequence "D%u", 0, 2)>;
70 def QRegs : MyClass<128, [i128], (sequence "Q%u", 0, 2)>;
72 def dsub0 : SubRegIndex<64>;
73 def dsub1 : SubRegIndex<64>;
74 def dsub2 : SubRegIndex<64>;
76 def ssub0 : SubRegIndex<32>;
77 def ssub1 : ComposedSubRegIndex<dsub1, ssub>;
78 def ssub2 : ComposedSubRegIndex<dsub2, ssub>;
80 def STuples2 : RegisterTuples<[ssub0, ssub1],
81 [(shl SRegs, 0), (shl SRegs, 1)]>;
82 def STuplesRC2 : MyClass<64, [untyped], (add STuples2)>;
84 def DTuples2 : RegisterTuples<[dsub0, dsub1],
85 [(shl DRegs, 0), (shl DRegs, 1)]>;
86 def DTuplesRC2 : MyClass<128, [untyped], (add DTuples2)>;
88 def STuples3 : RegisterTuples<[ssub0, ssub1, ssub2],
89 [(shl SRegs, 0), (shl SRegs, 1), (shl SRegs, 2)]>;
90 def STuplesRC3 : MyClass<96, [untyped], (add STuples3)>;
92 def DTuples3 : RegisterTuples<[dsub0, dsub1, dsub2],
93 [(shl DRegs, 0), (shl DRegs, 1), (shl DRegs, 2)]>;
94 def DTuplesRC3 : MyClass<192, [untyped], (add DTuples3)>;
96 def TestTarget : Target;
98 // CHECK: RegisterClass SRegs:
99 // CHECK: LaneMask: 0000000000000001
100 // CHECK: HasDisjunctSubRegs: 0
101 // CHECK: CoveredBySubRegs: 0
102 // CHECK: Regs: S0 S1 S2
103 // CHECK: SubClasses: SRegs
104 // CHECK: SuperClasses:
106 // CHECK: RegisterClass DRegs:
107 // CHECK: LaneMask: 0000000000000044
108 // CHECK: HasDisjunctSubRegs: 1
109 // CHECK: CoveredBySubRegs: 1
110 // CHECK: Regs: D0 D1 D2
111 // CHECK: SubClasses: DRegs
112 // CHECK: SuperClasses:
114 // CHECK: RegisterClass QRegs:
115 // CHECK: LaneMask: 0000000000000045
116 // CHECK: HasDisjunctSubRegs: 1
117 // CHECK: CoveredBySubRegs: 1
118 // CHECK: Regs: Q0 Q1 Q2
119 // CHECK: SubClasses: QRegs
120 // CHECK: SuperClasses:
122 // CHECK: SubRegIndex dsub:
123 // CHECK-NEXT: LaneMask: 0000000000000044
124 // CHECK: SubRegIndex dsub0:
125 // CHECK-NEXT: LaneMask: 0000000000000044
126 // CHECK: SubRegIndex dsub1:
127 // CHECK-NEXT: LaneMask: 0000000000000090
128 // CHECK: SubRegIndex dsub2:
129 // CHECK-NEXT: LaneMask: 0000000000000120
130 // CHECK: SubRegIndex dsub_hi:
131 // CHECK-NEXT: LaneMask: 0000000000000001
132 // CHECK: SubRegIndex ssub:
133 // CHECK-NEXT: LaneMask: 0000000000000004
134 // CHECK: SubRegIndex ssub0:
135 // CHECK-NEXT: LaneMask: 0000000000000008
136 // CHECK: SubRegIndex ssub1:
137 // CHECK-NEXT: LaneMask: 0000000000000010
138 // CHECK: SubRegIndex ssub2:
139 // CHECK-NEXT: LaneMask: 0000000000000020
140 // CHECK: SubRegIndex ssub_hi:
141 // CHECK-NEXT: LaneMask: 0000000000000040
142 // CHECK: SubRegIndex dsub1_then_ssub_hi:
143 // CHECK-NEXT: LaneMask: 0000000000000080
144 // CHECK: SubRegIndex dsub2_then_ssub_hi:
145 // CHECK-NEXT: LaneMask: 0000000000000100
146 // CHECK: SubRegIndex ssub_ssub1:
147 // CHECK-NEXT: LaneMask: 0000000000000014
148 // CHECK: SubRegIndex dsub0_dsub1:
149 // CHECK-NEXT: LaneMask: 00000000000000D4
150 // CHECK: SubRegIndex dsub1_dsub2:
151 // CHECK-NEXT: LaneMask: 00000000000001B0
152 // CHECK: SubRegIndex ssub_ssub1_ssub2:
153 // CHECK-NEXT: LaneMask: 0000000000000034
154 // CHECK: SubRegIndex ssub1_ssub2:
155 // CHECK-NEXT: LaneMask: 0000000000000030
156 // CHECK: SubRegIndex ssub0_ssub1:
157 // CHECK-NEXT: LaneMask: 0000000000000018
159 // CHECK: Register D0:
160 // CHECK: CoveredBySubregs: 1
161 // CHECK: HasDisjunctSubRegs: 1
162 // CHECK: SubReg ssub = S0
163 // CHECK: SubReg ssub_hi = S0_HI
165 // CHECK: Register Q0:
166 // CHECK: CoveredBySubregs: 1
167 // CHECK: HasDisjunctSubRegs: 1
168 // CHECK: SubReg dsub = D0
169 // CHECK: SubReg dsub_hi = D0_HI
170 // CHECK: SubReg ssub = S0
171 // CHECK: SubReg ssub_hi = S0_HI
173 // CHECK: Register S0:
174 // CHECK: CoveredBySubregs: 0
175 // CHECK: HasDisjunctSubRegs: 0
177 // CHECK: Register D0_D1:
178 // CHECK: CoveredBySubregs: 1
179 // CHECK: HasDisjunctSubRegs: 1
180 // CHECK: SubReg dsub0 = D0
181 // CHECK: SubReg dsub1 = D1
182 // CHECK: SubReg ssub = S0
183 // CHECK: SubReg ssub1 = S1
184 // CHECK: SubReg ssub_hi = S0_HI
185 // CHECK: SubReg dsub1_then_ssub_hi = S1_HI
186 // CHECK: SubReg ssub_ssub1 = S0_S1
188 // CHECK: Register D0_D1_D2:
189 // CHECK: CoveredBySubregs: 1
190 // CHECK: HasDisjunctSubRegs: 1
191 // CHECK: SubReg dsub0 = D0
192 // CHECK: SubReg dsub1 = D1
193 // CHECK: SubReg dsub2 = D2
194 // CHECK: SubReg ssub = S0
195 // CHECK: SubReg ssub1 = S1
196 // CHECK: SubReg ssub2 = S2
197 // CHECK: SubReg ssub_hi = S0_HI
198 // CHECK: SubReg dsub1_then_ssub_hi = S1_HI
199 // CHECK: SubReg dsub2_then_ssub_hi = S2_HI
200 // CHECK: SubReg ssub_ssub1 = S0_S1
201 // CHECK: SubReg dsub0_dsub1 = D0_D1
202 // CHECK: SubReg dsub1_dsub2 = D1_D2
203 // CHECK: SubReg ssub_ssub1_ssub2 = S0_S1_S2
204 // CHECK: SubReg ssub1_ssub2 = S1_S2
206 // CHECK: Register S0_S1:
207 // CHECK: CoveredBySubregs: 1
208 // CHECK: HasDisjunctSubRegs: 1
209 // CHECK: SubReg ssub0 = S0
210 // CHECK: SubReg ssub1 = S1
212 // CHECK: Register S0_S1_S2:
213 // CHECK: CoveredBySubregs: 1
214 // CHECK: HasDisjunctSubRegs: 1
215 // CHECK: SubReg ssub0 = S0
216 // CHECK: SubReg ssub1 = S1
217 // CHECK: SubReg ssub2 = S2
218 // CHECK: SubReg ssub1_ssub2 = S1_S2
219 // CHECK: SubReg ssub0_ssub1 = S0_S1