1/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2|* *|
3|* Target Register and Register Classes Information *|
4|* *|
5|* Automatically generated file, do not edit! *|
6|* *|
7\*===----------------------------------------------------------------------===*/
8
9namespace llvm {
10
11extern const MCRegisterClass LoongArchMCRegisterClasses[];
12
13static const MVT::SimpleValueType VTLists[] = {
14 /* 0 */ MVT::i32, MVT::Other,
15 /* 2 */ MVT::i64, MVT::Other,
16 /* 4 */ MVT::f32, MVT::Other,
17 /* 6 */ MVT::f64, MVT::Other,
18 /* 8 */ MVT::v4f32, MVT::v2f64, MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64, MVT::Other,
19 /* 15 */ MVT::v8f32, MVT::v4f64, MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64, MVT::Other,
20};
21
22static const char *SubRegIndexNameTable[] = { "sub_32", "sub_64", "sub_128", "" };
23
24static const TargetRegisterInfo::SubRegCoveredBits SubRegIdxRangeTable[] = {
25 { .Offset: 65535, .Size: 65535 },
26 { .Offset: 0, .Size: 32 }, // sub_32
27 { .Offset: 0, .Size: 64 }, // sub_64
28 { .Offset: 0, .Size: 128 }, // sub_128
29 { .Offset: 65535, .Size: 65535 },
30 { .Offset: 0, .Size: 32 }, // sub_32
31 { .Offset: 0, .Size: 64 }, // sub_64
32 { .Offset: 0, .Size: 128 }, // sub_128
33};
34
35
36static const LaneBitmask SubRegIndexLaneMaskTable[] = {
37 LaneBitmask::getAll(),
38 LaneBitmask(0x0000000000000001), // sub_32
39 LaneBitmask(0x0000000000000001), // sub_64
40 LaneBitmask(0x0000000000000001), // sub_128
41 };
42
43
44
45static const TargetRegisterInfo::RegClassInfo RegClassInfos[] = {
46 // Mode = 0 (Default)
47 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 4 }, // FPR32
48 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 0 }, // GPR
49 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 0 }, // GPRJR
50 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 0 }, // GPRNoR0R1
51 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 0 }, // GPRT
52 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 0 }, // CFR
53 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 0 }, // FCSR
54 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 0 }, // SCR
55 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*VTLists+*/.VTListOffset: 6 }, // FPR64
56 { .RegSize: 128, .SpillSize: 128, .SpillAlignment: 128, /*VTLists+*/.VTListOffset: 8 }, // LSX128
57 { .RegSize: 256, .SpillSize: 256, .SpillAlignment: 256, /*VTLists+*/.VTListOffset: 15 }, // LASX256
58 // Mode = 1 (LA64)
59 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 4 }, // FPR32
60 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*VTLists+*/.VTListOffset: 2 }, // GPR
61 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*VTLists+*/.VTListOffset: 2 }, // GPRJR
62 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*VTLists+*/.VTListOffset: 2 }, // GPRNoR0R1
63 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*VTLists+*/.VTListOffset: 2 }, // GPRT
64 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*VTLists+*/.VTListOffset: 2 }, // CFR
65 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*VTLists+*/.VTListOffset: 0 }, // FCSR
66 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*VTLists+*/.VTListOffset: 2 }, // SCR
67 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*VTLists+*/.VTListOffset: 6 }, // FPR64
68 { .RegSize: 128, .SpillSize: 128, .SpillAlignment: 128, /*VTLists+*/.VTListOffset: 8 }, // LSX128
69 { .RegSize: 256, .SpillSize: 256, .SpillAlignment: 256, /*VTLists+*/.VTListOffset: 15 }, // LASX256
70};
71static const uint32_t FPR32SubClassMask[] = {
72 0x00000001,
73 0x00000700, // sub_32
74};
75
76static const uint32_t GPRSubClassMask[] = {
77 0x0000001e,
78};
79
80static const uint32_t GPRJRSubClassMask[] = {
81 0x0000001c,
82};
83
84static const uint32_t GPRNoR0R1SubClassMask[] = {
85 0x00000018,
86};
87
88static const uint32_t GPRTSubClassMask[] = {
89 0x00000010,
90};
91
92static const uint32_t CFRSubClassMask[] = {
93 0x00000020,
94};
95
96static const uint32_t FCSRSubClassMask[] = {
97 0x00000040,
98};
99
100static const uint32_t SCRSubClassMask[] = {
101 0x00000080,
102};
103
104static const uint32_t FPR64SubClassMask[] = {
105 0x00000100,
106 0x00000600, // sub_64
107};
108
109static const uint32_t LSX128SubClassMask[] = {
110 0x00000200,
111 0x00000400, // sub_128
112};
113
114static const uint32_t LASX256SubClassMask[] = {
115 0x00000400,
116};
117
118static const uint16_t SuperRegIdxSeqs[] = {
119 /* 0 */ 1, 0,
120 /* 2 */ 2, 0,
121 /* 4 */ 3, 0,
122};
123
124static unsigned const GPRJRSuperclasses[] = {
125 LoongArch::GPRRegClassID,
126};
127
128static unsigned const GPRNoR0R1Superclasses[] = {
129 LoongArch::GPRRegClassID,
130 LoongArch::GPRJRRegClassID,
131};
132
133static unsigned const GPRTSuperclasses[] = {
134 LoongArch::GPRRegClassID,
135 LoongArch::GPRJRRegClassID,
136 LoongArch::GPRNoR0R1RegClassID,
137};
138
139
140namespace LoongArch { // Register class instances
141 extern const TargetRegisterClass FPR32RegClass = {
142 .MC: &LoongArchMCRegisterClasses[FPR32RegClassID],
143 .SubClassMask: FPR32SubClassMask,
144 .SuperRegIndices: SuperRegIdxSeqs + 0,
145 .LaneMask: LaneBitmask(0x0000000000000001),
146 .AllocationPriority: 0,
147 .GlobalPriority: false,
148 .TSFlags: 0x00, /* TSFlags */
149 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
150 .CoveredBySubRegs: false, /* CoveredBySubRegs */
151 .SuperClasses: nullptr, .SuperClassesSize: 0,
152 .OrderFunc: nullptr
153 };
154
155 extern const TargetRegisterClass GPRRegClass = {
156 .MC: &LoongArchMCRegisterClasses[GPRRegClassID],
157 .SubClassMask: GPRSubClassMask,
158 .SuperRegIndices: SuperRegIdxSeqs + 1,
159 .LaneMask: LaneBitmask(0x0000000000000001),
160 .AllocationPriority: 0,
161 .GlobalPriority: false,
162 .TSFlags: 0x00, /* TSFlags */
163 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
164 .CoveredBySubRegs: false, /* CoveredBySubRegs */
165 .SuperClasses: nullptr, .SuperClassesSize: 0,
166 .OrderFunc: nullptr
167 };
168
169 extern const TargetRegisterClass GPRJRRegClass = {
170 .MC: &LoongArchMCRegisterClasses[GPRJRRegClassID],
171 .SubClassMask: GPRJRSubClassMask,
172 .SuperRegIndices: SuperRegIdxSeqs + 1,
173 .LaneMask: LaneBitmask(0x0000000000000001),
174 .AllocationPriority: 0,
175 .GlobalPriority: false,
176 .TSFlags: 0x00, /* TSFlags */
177 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
178 .CoveredBySubRegs: false, /* CoveredBySubRegs */
179 .SuperClasses: GPRJRSuperclasses, .SuperClassesSize: 1,
180 .OrderFunc: nullptr
181 };
182
183 extern const TargetRegisterClass GPRNoR0R1RegClass = {
184 .MC: &LoongArchMCRegisterClasses[GPRNoR0R1RegClassID],
185 .SubClassMask: GPRNoR0R1SubClassMask,
186 .SuperRegIndices: SuperRegIdxSeqs + 1,
187 .LaneMask: LaneBitmask(0x0000000000000001),
188 .AllocationPriority: 0,
189 .GlobalPriority: false,
190 .TSFlags: 0x00, /* TSFlags */
191 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
192 .CoveredBySubRegs: false, /* CoveredBySubRegs */
193 .SuperClasses: GPRNoR0R1Superclasses, .SuperClassesSize: 2,
194 .OrderFunc: nullptr
195 };
196
197 extern const TargetRegisterClass GPRTRegClass = {
198 .MC: &LoongArchMCRegisterClasses[GPRTRegClassID],
199 .SubClassMask: GPRTSubClassMask,
200 .SuperRegIndices: SuperRegIdxSeqs + 1,
201 .LaneMask: LaneBitmask(0x0000000000000001),
202 .AllocationPriority: 0,
203 .GlobalPriority: false,
204 .TSFlags: 0x00, /* TSFlags */
205 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
206 .CoveredBySubRegs: false, /* CoveredBySubRegs */
207 .SuperClasses: GPRTSuperclasses, .SuperClassesSize: 3,
208 .OrderFunc: nullptr
209 };
210
211 extern const TargetRegisterClass CFRRegClass = {
212 .MC: &LoongArchMCRegisterClasses[CFRRegClassID],
213 .SubClassMask: CFRSubClassMask,
214 .SuperRegIndices: SuperRegIdxSeqs + 1,
215 .LaneMask: LaneBitmask(0x0000000000000001),
216 .AllocationPriority: 0,
217 .GlobalPriority: false,
218 .TSFlags: 0x00, /* TSFlags */
219 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
220 .CoveredBySubRegs: false, /* CoveredBySubRegs */
221 .SuperClasses: nullptr, .SuperClassesSize: 0,
222 .OrderFunc: nullptr
223 };
224
225 extern const TargetRegisterClass FCSRRegClass = {
226 .MC: &LoongArchMCRegisterClasses[FCSRRegClassID],
227 .SubClassMask: FCSRSubClassMask,
228 .SuperRegIndices: SuperRegIdxSeqs + 1,
229 .LaneMask: LaneBitmask(0x0000000000000001),
230 .AllocationPriority: 0,
231 .GlobalPriority: false,
232 .TSFlags: 0x00, /* TSFlags */
233 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
234 .CoveredBySubRegs: false, /* CoveredBySubRegs */
235 .SuperClasses: nullptr, .SuperClassesSize: 0,
236 .OrderFunc: nullptr
237 };
238
239 extern const TargetRegisterClass SCRRegClass = {
240 .MC: &LoongArchMCRegisterClasses[SCRRegClassID],
241 .SubClassMask: SCRSubClassMask,
242 .SuperRegIndices: SuperRegIdxSeqs + 1,
243 .LaneMask: LaneBitmask(0x0000000000000001),
244 .AllocationPriority: 0,
245 .GlobalPriority: false,
246 .TSFlags: 0x00, /* TSFlags */
247 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
248 .CoveredBySubRegs: false, /* CoveredBySubRegs */
249 .SuperClasses: nullptr, .SuperClassesSize: 0,
250 .OrderFunc: nullptr
251 };
252
253 extern const TargetRegisterClass FPR64RegClass = {
254 .MC: &LoongArchMCRegisterClasses[FPR64RegClassID],
255 .SubClassMask: FPR64SubClassMask,
256 .SuperRegIndices: SuperRegIdxSeqs + 2,
257 .LaneMask: LaneBitmask(0x0000000000000001),
258 .AllocationPriority: 0,
259 .GlobalPriority: false,
260 .TSFlags: 0x00, /* TSFlags */
261 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
262 .CoveredBySubRegs: false, /* CoveredBySubRegs */
263 .SuperClasses: nullptr, .SuperClassesSize: 0,
264 .OrderFunc: nullptr
265 };
266
267 extern const TargetRegisterClass LSX128RegClass = {
268 .MC: &LoongArchMCRegisterClasses[LSX128RegClassID],
269 .SubClassMask: LSX128SubClassMask,
270 .SuperRegIndices: SuperRegIdxSeqs + 4,
271 .LaneMask: LaneBitmask(0x0000000000000001),
272 .AllocationPriority: 0,
273 .GlobalPriority: false,
274 .TSFlags: 0x00, /* TSFlags */
275 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
276 .CoveredBySubRegs: false, /* CoveredBySubRegs */
277 .SuperClasses: nullptr, .SuperClassesSize: 0,
278 .OrderFunc: nullptr
279 };
280
281 extern const TargetRegisterClass LASX256RegClass = {
282 .MC: &LoongArchMCRegisterClasses[LASX256RegClassID],
283 .SubClassMask: LASX256SubClassMask,
284 .SuperRegIndices: SuperRegIdxSeqs + 1,
285 .LaneMask: LaneBitmask(0x0000000000000001),
286 .AllocationPriority: 0,
287 .GlobalPriority: false,
288 .TSFlags: 0x00, /* TSFlags */
289 .HasDisjunctSubRegs: false, /* HasDisjunctSubRegs */
290 .CoveredBySubRegs: false, /* CoveredBySubRegs */
291 .SuperClasses: nullptr, .SuperClassesSize: 0,
292 .OrderFunc: nullptr
293 };
294
295} // end namespace LoongArch
296
297namespace {
298 const TargetRegisterClass *const RegisterClasses[] = {
299 &LoongArch::FPR32RegClass,
300 &LoongArch::GPRRegClass,
301 &LoongArch::GPRJRRegClass,
302 &LoongArch::GPRNoR0R1RegClass,
303 &LoongArch::GPRTRegClass,
304 &LoongArch::CFRRegClass,
305 &LoongArch::FCSRRegClass,
306 &LoongArch::SCRRegClass,
307 &LoongArch::FPR64RegClass,
308 &LoongArch::LSX128RegClass,
309 &LoongArch::LASX256RegClass,
310 };
311} // end anonymous namespace
312
313static const uint8_t CostPerUseTable[] = {
3140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
315
316
317static const bool InAllocatableClassTable[] = {
318false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, };
319
320
321static const TargetRegisterInfoDesc LoongArchRegInfoDesc = { // Extra Descriptors
322.CostPerUse: CostPerUseTable, .NumCosts: 1, .InAllocatableClass: InAllocatableClassTable};
323
324unsigned LoongArchGenRegisterInfo::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {
325 static const uint8_t Rows[1][3] = {
326 { LoongArch::sub_32, LoongArch::sub_64, 0, },
327 };
328
329 --IdxA; assert(IdxA < 3); (void) IdxA;
330 --IdxB; assert(IdxB < 3);
331 return Rows[0][IdxB];
332}
333
334unsigned LoongArchGenRegisterInfo::reverseComposeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {
335 static const uint8_t Table[3][3] = {
336 { LoongArch::sub_32, LoongArch::sub_64, 0, },
337 { LoongArch::sub_32, LoongArch::sub_64, 0, },
338 { LoongArch::sub_32, LoongArch::sub_64, 0, },
339 };
340
341 --IdxA; assert(IdxA < 3);
342 --IdxB; assert(IdxB < 3);
343 return Table[IdxA][IdxB];
344 }
345
346 struct MaskRolOp {
347 LaneBitmask Mask;
348 uint8_t RotateLeft;
349 };
350 static const MaskRolOp LaneMaskComposeSequences[] = {
351 { .Mask: LaneBitmask(0xFFFFFFFFFFFFFFFF), .RotateLeft: 0 }, { .Mask: LaneBitmask::getNone(), .RotateLeft: 0 } // Sequence 0
352 };
353 static const uint8_t CompositeSequences[] = {
354 0, // to sub_32
355 0, // to sub_64
356 0 // to sub_128
357 };
358
359LaneBitmask LoongArchGenRegisterInfo::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask) const {
360 --IdxA; assert(IdxA < 3 && "Subregister index out of bounds");
361 LaneBitmask Result;
362 for (const MaskRolOp *Ops =
363 &LaneMaskComposeSequences[CompositeSequences[IdxA]];
364 Ops->Mask.any(); ++Ops) {
365 LaneBitmask::Type M = LaneMask.getAsInteger() & Ops->Mask.getAsInteger();
366 if (unsigned S = Ops->RotateLeft)
367 Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - S)));
368 else
369 Result |= LaneBitmask(M);
370 }
371 return Result;
372}
373
374LaneBitmask LoongArchGenRegisterInfo::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask) const {
375 LaneMask &= getSubRegIndexLaneMask(SubIdx: IdxA);
376 --IdxA; assert(IdxA < 3 && "Subregister index out of bounds");
377 LaneBitmask Result;
378 for (const MaskRolOp *Ops =
379 &LaneMaskComposeSequences[CompositeSequences[IdxA]];
380 Ops->Mask.any(); ++Ops) {
381 LaneBitmask::Type M = LaneMask.getAsInteger();
382 if (unsigned S = Ops->RotateLeft)
383 Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - S)));
384 else
385 Result |= LaneBitmask(M);
386 }
387 return Result;
388}
389
390const TargetRegisterClass *LoongArchGenRegisterInfo::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const {
391 static const uint8_t Table[11][3] = {
392 { // FPR32
393 0, // sub_32
394 0, // sub_64
395 0, // sub_128
396 },
397 { // GPR
398 0, // sub_32
399 0, // sub_64
400 0, // sub_128
401 },
402 { // GPRJR
403 0, // sub_32
404 0, // sub_64
405 0, // sub_128
406 },
407 { // GPRNoR0R1
408 0, // sub_32
409 0, // sub_64
410 0, // sub_128
411 },
412 { // GPRT
413 0, // sub_32
414 0, // sub_64
415 0, // sub_128
416 },
417 { // CFR
418 0, // sub_32
419 0, // sub_64
420 0, // sub_128
421 },
422 { // FCSR
423 0, // sub_32
424 0, // sub_64
425 0, // sub_128
426 },
427 { // SCR
428 0, // sub_32
429 0, // sub_64
430 0, // sub_128
431 },
432 { // FPR64
433 9, // sub_32 -> FPR64
434 0, // sub_64
435 0, // sub_128
436 },
437 { // LSX128
438 10, // sub_32 -> LSX128
439 10, // sub_64 -> LSX128
440 0, // sub_128
441 },
442 { // LASX256
443 11, // sub_32 -> LASX256
444 11, // sub_64 -> LASX256
445 11, // sub_128 -> LASX256
446 },
447 };
448 assert(RC && "Missing regclass");
449 if (!Idx) return RC;
450 --Idx;
451 assert(Idx < 3 && "Bad subreg");
452 unsigned TV = Table[RC->getID()][Idx];
453 return TV ? getRegClass(i: TV - 1) : nullptr;
454}
455
456const TargetRegisterClass *LoongArchGenRegisterInfo::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx) const {
457 static const uint8_t Table[11][3] = {
458 { // FPR32
459 0, // FPR32:sub_32
460 0, // FPR32:sub_64
461 0, // FPR32:sub_128
462 },
463 { // GPR
464 0, // GPR:sub_32
465 0, // GPR:sub_64
466 0, // GPR:sub_128
467 },
468 { // GPRJR
469 0, // GPRJR:sub_32
470 0, // GPRJR:sub_64
471 0, // GPRJR:sub_128
472 },
473 { // GPRNoR0R1
474 0, // GPRNoR0R1:sub_32
475 0, // GPRNoR0R1:sub_64
476 0, // GPRNoR0R1:sub_128
477 },
478 { // GPRT
479 0, // GPRT:sub_32
480 0, // GPRT:sub_64
481 0, // GPRT:sub_128
482 },
483 { // CFR
484 0, // CFR:sub_32
485 0, // CFR:sub_64
486 0, // CFR:sub_128
487 },
488 { // FCSR
489 0, // FCSR:sub_32
490 0, // FCSR:sub_64
491 0, // FCSR:sub_128
492 },
493 { // SCR
494 0, // SCR:sub_32
495 0, // SCR:sub_64
496 0, // SCR:sub_128
497 },
498 { // FPR64
499 1, // FPR64:sub_32 -> FPR32
500 0, // FPR64:sub_64
501 0, // FPR64:sub_128
502 },
503 { // LSX128
504 1, // LSX128:sub_32 -> FPR32
505 9, // LSX128:sub_64 -> FPR64
506 0, // LSX128:sub_128
507 },
508 { // LASX256
509 1, // LASX256:sub_32 -> FPR32
510 9, // LASX256:sub_64 -> FPR64
511 10, // LASX256:sub_128 -> LSX128
512 },
513 };
514 assert(RC && "Missing regclass");
515 if (!Idx) return RC;
516 --Idx;
517 assert(Idx < 3 && "Bad subreg");
518 unsigned TV = Table[RC->getID()][Idx];
519 return TV ? getRegClass(i: TV - 1) : nullptr;
520}
521
522/// Get the weight in units of pressure for this register class.
523const RegClassWeight &LoongArchGenRegisterInfo::
524getRegClassWeight(const TargetRegisterClass *RC) const {
525 static const RegClassWeight RCWeightTable[] = {
526 {.RegWeight: 1, .WeightLimit: 32}, // FPR32
527 {.RegWeight: 1, .WeightLimit: 32}, // GPR
528 {.RegWeight: 1, .WeightLimit: 31}, // GPRJR
529 {.RegWeight: 1, .WeightLimit: 30}, // GPRNoR0R1
530 {.RegWeight: 1, .WeightLimit: 17}, // GPRT
531 {.RegWeight: 1, .WeightLimit: 8}, // CFR
532 {.RegWeight: 0, .WeightLimit: 0}, // FCSR
533 {.RegWeight: 0, .WeightLimit: 0}, // SCR
534 {.RegWeight: 1, .WeightLimit: 32}, // FPR64
535 {.RegWeight: 1, .WeightLimit: 32}, // LSX128
536 {.RegWeight: 1, .WeightLimit: 32}, // LASX256
537 };
538 return RCWeightTable[RC->getID()];
539}
540
541/// Get the weight in units of pressure for this register unit.
542unsigned LoongArchGenRegisterInfo::
543getRegUnitWeight(MCRegUnit RegUnit) const {
544 assert(static_cast<unsigned>(RegUnit) < 80 && "invalid register unit");
545 // All register units have unit weight.
546 return 1;
547}
548
549
550// Get the number of dimensions of register pressure.
551unsigned LoongArchGenRegisterInfo::getNumRegPressureSets() const {
552 return 4;
553}
554
555// Get the name of this register unit pressure set.
556const char *LoongArchGenRegisterInfo::
557getRegPressureSetName(unsigned Idx) const {
558 static const char *PressureNameTable[] = {
559 "CFR",
560 "GPRT",
561 "FPR32",
562 "GPR",
563 };
564 return PressureNameTable[Idx];
565}
566
567// Get the register unit pressure limit for this dimension.
568// This limit must be adjusted dynamically for reserved registers.
569unsigned LoongArchGenRegisterInfo::
570getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const {
571 static const uint8_t PressureLimitTable[] = {
572 8, // 0: CFR
573 17, // 1: GPRT
574 32, // 2: FPR32
575 32, // 3: GPR
576 };
577 return PressureLimitTable[Idx];
578}
579
580/// Table of pressure sets per register class or unit.
581static const int RCSetsTable[] = {
582 /* 0 */ 0, -1,
583 /* 2 */ 2, -1,
584 /* 4 */ 1, 3, -1,
585};
586
587/// Get the dimensions of register pressure impacted by this register class.
588/// Returns a -1 terminated array of pressure set IDs
589const int *LoongArchGenRegisterInfo::
590getRegClassPressureSets(const TargetRegisterClass *RC) const {
591 static const uint8_t RCSetStartTable[] = {
592 2,5,5,5,4,0,1,1,2,2,2,};
593 return &RCSetsTable[RCSetStartTable[RC->getID()]];
594}
595
596/// Get the dimensions of register pressure impacted by this register unit.
597/// Returns a -1 terminated array of pressure set IDs
598const int *LoongArchGenRegisterInfo::
599getRegUnitPressureSets(MCRegUnit RegUnit) const {
600 assert(static_cast<unsigned>(RegUnit) < 80 && "invalid register unit");
601 static const uint8_t RUSetStartTable[] = {
602 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,1,1,1,1,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,1,1,1,1,};
603 return &RCSetsTable[RUSetStartTable[static_cast<unsigned>(RegUnit)]];
604}
605
606extern const MCRegisterDesc LoongArchRegDesc[];
607extern const int16_t LoongArchRegDiffLists[];
608extern const LaneBitmask LoongArchLaneMaskLists[];
609extern const char LoongArchRegStrings[];
610extern const char LoongArchRegClassStrings[];
611extern const MCPhysReg LoongArchRegUnitRoots[][2];
612extern const uint16_t LoongArchSubRegIdxLists[];
613extern const uint16_t LoongArchRegEncodingTable[];
614// LoongArch Dwarf<->LLVM register mappings.
615extern const MCRegisterInfo::DwarfLLVMRegPair LoongArchDwarfFlavour0Dwarf2L[];
616extern const unsigned LoongArchDwarfFlavour0Dwarf2LSize;
617
618extern const MCRegisterInfo::DwarfLLVMRegPair LoongArchEHFlavour0Dwarf2L[];
619extern const unsigned LoongArchEHFlavour0Dwarf2LSize;
620
621extern const MCRegisterInfo::DwarfLLVMRegPair LoongArchDwarfFlavour0L2Dwarf[];
622extern const unsigned LoongArchDwarfFlavour0L2DwarfSize;
623
624extern const MCRegisterInfo::DwarfLLVMRegPair LoongArchEHFlavour0L2Dwarf[];
625extern const unsigned LoongArchEHFlavour0L2DwarfSize;
626
627LoongArchGenRegisterInfo::
628LoongArchGenRegisterInfo(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,
629 unsigned PC, unsigned HwMode)
630 : TargetRegisterInfo(&LoongArchRegInfoDesc, RegisterClasses, RegisterClasses+11,
631 SubRegIndexNameTable, SubRegIdxRangeTable, SubRegIndexLaneMaskTable,
632 LaneBitmask(0xFFFFFFFFFFFFFFFE), RegClassInfos, VTLists, HwMode) {
633 InitMCRegisterInfo(D: LoongArchRegDesc, NR: 177, RA, PC,
634 C: LoongArchMCRegisterClasses, NC: 11,
635 RURoots: LoongArchRegUnitRoots,
636 NRU: 80,
637 DL: LoongArchRegDiffLists,
638 RUMS: LoongArchLaneMaskLists,
639 Strings: LoongArchRegStrings,
640 ClassStrings: LoongArchRegClassStrings,
641 SubIndices: LoongArchSubRegIdxLists,
642 NumIndices: 4,
643 RET: LoongArchRegEncodingTable);
644
645 switch (DwarfFlavour) {
646 default:
647 llvm_unreachable("Unknown DWARF flavour");
648 case 0:
649 mapDwarfRegsToLLVMRegs(Map: LoongArchDwarfFlavour0Dwarf2L, Size: LoongArchDwarfFlavour0Dwarf2LSize, isEH: false);
650 break;
651 }
652 switch (EHFlavour) {
653 default:
654 llvm_unreachable("Unknown DWARF flavour");
655 case 0:
656 mapDwarfRegsToLLVMRegs(Map: LoongArchEHFlavour0Dwarf2L, Size: LoongArchEHFlavour0Dwarf2LSize, isEH: true);
657 break;
658 }
659 switch (DwarfFlavour) {
660 default:
661 llvm_unreachable("Unknown DWARF flavour");
662 case 0:
663 mapLLVMRegsToDwarfRegs(Map: LoongArchDwarfFlavour0L2Dwarf, Size: LoongArchDwarfFlavour0L2DwarfSize, isEH: false);
664 break;
665 }
666 switch (EHFlavour) {
667 default:
668 llvm_unreachable("Unknown DWARF flavour");
669 case 0:
670 mapLLVMRegsToDwarfRegs(Map: LoongArchEHFlavour0L2Dwarf, Size: LoongArchEHFlavour0L2DwarfSize, isEH: true);
671 break;
672 }
673}
674
675static const MCPhysReg CSR_ILP32D_LP64D_SaveList[] = { LoongArch::R1, LoongArch::R22, LoongArch::R23, LoongArch::R24, LoongArch::R25, LoongArch::R26, LoongArch::R27, LoongArch::R28, LoongArch::R29, LoongArch::R30, LoongArch::R31, LoongArch::F24_64, LoongArch::F25_64, LoongArch::F26_64, LoongArch::F27_64, LoongArch::F28_64, LoongArch::F29_64, LoongArch::F30_64, LoongArch::F31_64, 0 };
676static const uint32_t CSR_ILP32D_LP64D_RegMask[] = { 0xfe000000, 0x00006001, 0x00001ff8, 0x00000000, 0x00000000, 0x0001fe00, };
677static const MCPhysReg CSR_ILP32F_LP64F_SaveList[] = { LoongArch::R1, LoongArch::R22, LoongArch::R23, LoongArch::R24, LoongArch::R25, LoongArch::R26, LoongArch::R27, LoongArch::R28, LoongArch::R29, LoongArch::R30, LoongArch::R31, LoongArch::F24, LoongArch::F25, LoongArch::F26, LoongArch::F27, LoongArch::F28, LoongArch::F29, LoongArch::F30, LoongArch::F31, 0 };
678static const uint32_t CSR_ILP32F_LP64F_RegMask[] = { 0xfe000000, 0x00006001, 0x00001ff8, 0x00000000, 0x00000000, 0x00000000, };
679static const MCPhysReg CSR_ILP32S_LP64S_SaveList[] = { LoongArch::R1, LoongArch::R22, LoongArch::R23, LoongArch::R24, LoongArch::R25, LoongArch::R26, LoongArch::R27, LoongArch::R28, LoongArch::R29, LoongArch::R30, LoongArch::R31, 0 };
680static const uint32_t CSR_ILP32S_LP64S_RegMask[] = { 0x00000000, 0x00006000, 0x00001ff8, 0x00000000, 0x00000000, 0x00000000, };
681static const MCPhysReg CSR_MostRegs_SaveList[] = { LoongArch::R1, LoongArch::R22, LoongArch::R23, LoongArch::R24, LoongArch::R25, LoongArch::R26, LoongArch::R27, LoongArch::R28, LoongArch::R29, LoongArch::R30, LoongArch::R31, LoongArch::R4, LoongArch::R5, LoongArch::R6, LoongArch::R7, LoongArch::R8, LoongArch::R9, LoongArch::R10, LoongArch::R11, LoongArch::R16, LoongArch::R17, LoongArch::R18, LoongArch::R19, 0 };
682static const uint32_t CSR_MostRegs_RegMask[] = { 0x00000000, 0xe1fe6000, 0x00001ff9, 0x00000000, 0x00000000, 0x00000000, };
683static const MCPhysReg CSR_NoRegs_SaveList[] = { 0 };
684static const uint32_t CSR_NoRegs_RegMask[] = { 0x00000000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, };
685static const MCPhysReg CSR_NoneRegs_SaveList[] = { LoongArch::R1, LoongArch::R22, 0 };
686static const uint32_t CSR_NoneRegs_RegMask[] = { 0x00000000, 0x00006000, 0x00000008, 0x00000000, 0x00000000, 0x00000000, };
687
688
689ArrayRef<const uint32_t *> LoongArchGenRegisterInfo::getRegMasks() const {
690 static const uint32_t *const Masks[] = {
691 CSR_ILP32D_LP64D_RegMask,
692 CSR_ILP32F_LP64F_RegMask,
693 CSR_ILP32S_LP64S_RegMask,
694 CSR_MostRegs_RegMask,
695 CSR_NoRegs_RegMask,
696 CSR_NoneRegs_RegMask,
697 };
698 return ArrayRef(Masks);
699}
700
701bool LoongArchGenRegisterInfo::
702isGeneralPurposeRegister(const MachineFunction &MF, MCRegister PhysReg) const {
703 return
704 false;
705}
706
707bool LoongArchGenRegisterInfo::
708isGeneralPurposeRegisterClass(const TargetRegisterClass *RC) const {
709 return
710 false;
711}
712
713bool LoongArchGenRegisterInfo::
714isFixedRegister(const MachineFunction &MF, MCRegister PhysReg) const {
715 return
716 false;
717}
718
719bool LoongArchGenRegisterInfo::
720isArgumentRegister(const MachineFunction &MF, MCRegister PhysReg) const {
721 return
722 false;
723}
724
725bool LoongArchGenRegisterInfo::
726isConstantPhysReg(MCRegister PhysReg) const {
727 return
728 PhysReg == LoongArch::R0 ||
729 false;
730}
731
732ArrayRef<const char *> LoongArchGenRegisterInfo::getRegMaskNames() const {
733 static const char *Names[] = {
734 "CSR_ILP32D_LP64D",
735 "CSR_ILP32F_LP64F",
736 "CSR_ILP32S_LP64S",
737 "CSR_MostRegs",
738 "CSR_NoRegs",
739 "CSR_NoneRegs",
740 };
741 return ArrayRef(Names);
742}
743
744const LoongArchFrameLowering *
745LoongArchGenRegisterInfo::getFrameLowering(const MachineFunction &MF) {
746 return static_cast<const LoongArchFrameLowering *>(
747 MF.getSubtarget().getFrameLowering());
748}
749
750} // end namespace llvm
751
752