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