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 LoongArchVTLists[] = {
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 LoongArchSubRegIdxRangeTable[] = {
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 LoongArchSubRegIndexLaneMaskTable[] = {
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 LoongArchRegClassInfos[] = {
64 // Mode = 0 (DefaultMode)
65 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 4 }, // FPR32
66 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 0 }, // GPR
67 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 0 }, // GPRJR
68 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 0 }, // GPRNoR0R1
69 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 0 }, // GPRT
70 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 0 }, // CFR
71 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 0 }, // FCSR
72 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 0 }, // SCR
73 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*LoongArchVTLists+*/.VTListOffset: 6 }, // FPR64
74 { .RegSize: 128, .SpillSize: 128, .SpillAlignment: 128, /*LoongArchVTLists+*/.VTListOffset: 8 }, // LSX128
75 { .RegSize: 256, .SpillSize: 256, .SpillAlignment: 256, /*LoongArchVTLists+*/.VTListOffset: 15 }, // LASX256
76 // Mode = 1 (LA64)
77 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 4 }, // FPR32
78 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*LoongArchVTLists+*/.VTListOffset: 2 }, // GPR
79 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*LoongArchVTLists+*/.VTListOffset: 2 }, // GPRJR
80 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*LoongArchVTLists+*/.VTListOffset: 2 }, // GPRNoR0R1
81 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*LoongArchVTLists+*/.VTListOffset: 2 }, // GPRT
82 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*LoongArchVTLists+*/.VTListOffset: 2 }, // CFR
83 { .RegSize: 32, .SpillSize: 32, .SpillAlignment: 32, /*LoongArchVTLists+*/.VTListOffset: 0 }, // FCSR
84 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*LoongArchVTLists+*/.VTListOffset: 2 }, // SCR
85 { .RegSize: 64, .SpillSize: 64, .SpillAlignment: 64, /*LoongArchVTLists+*/.VTListOffset: 6 }, // FPR64
86 { .RegSize: 128, .SpillSize: 128, .SpillAlignment: 128, /*LoongArchVTLists+*/.VTListOffset: 8 }, // LSX128
87 { .RegSize: 256, .SpillSize: 256, .SpillAlignment: 256, /*LoongArchVTLists+*/.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
316static const TargetRegisterClass *const LoongArchRegisterClasses[] = {
317 &LoongArch::FPR32RegClass,
318 &LoongArch::GPRRegClass,
319 &LoongArch::GPRJRRegClass,
320 &LoongArch::GPRNoR0R1RegClass,
321 &LoongArch::GPRTRegClass,
322 &LoongArch::CFRRegClass,
323 &LoongArch::FCSRRegClass,
324 &LoongArch::SCRRegClass,
325 &LoongArch::FPR64RegClass,
326 &LoongArch::LSX128RegClass,
327 &LoongArch::LASX256RegClass,
328 };
329
330static const uint8_t LoongArchCostPerUseTable[] = {
3310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
332
333
334static const bool LoongArchInAllocatableClassTable[] = {
335false, 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, };
336
337
338static const TargetRegisterInfoDesc LoongArchRegInfoDesc = { // Extra Descriptors
339.CostPerUse: LoongArchCostPerUseTable, .NumCosts: 1, .InAllocatableClass: LoongArchInAllocatableClassTable};
340
341unsigned LoongArchGenRegisterInfo::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {
342 static const uint8_t Rows[1][3] = {
343 { LoongArch::sub_32, LoongArch::sub_64, 0, },
344 };
345
346 --IdxA; assert(IdxA < 3); (void) IdxA;
347 --IdxB; assert(IdxB < 3);
348 return Rows[0][IdxB];
349}
350
351unsigned LoongArchGenRegisterInfo::reverseComposeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {
352 static const uint8_t Table[3][3] = {
353 { LoongArch::sub_32, LoongArch::sub_64, 0, },
354 { LoongArch::sub_32, LoongArch::sub_64, 0, },
355 { LoongArch::sub_32, LoongArch::sub_64, 0, },
356 };
357
358 --IdxA; assert(IdxA < 3);
359 --IdxB; assert(IdxB < 3);
360 return Table[IdxA][IdxB];
361 }
362
363 struct MaskRolOp {
364 LaneBitmask Mask;
365 uint8_t RotateLeft;
366 };
367 static const MaskRolOp LaneMaskComposeSequences[] = {
368 { .Mask: LaneBitmask(0xFFFFFFFFFFFFFFFF), .RotateLeft: 0 }, { .Mask: LaneBitmask::getNone(), .RotateLeft: 0 } // Sequence 0
369 };
370 static const uint8_t CompositeSequences[] = {
371 0, // to sub_32
372 0, // to sub_64
373 0 // to sub_128
374 };
375
376LaneBitmask LoongArchGenRegisterInfo::composeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask) const {
377 --IdxA; assert(IdxA < 3 && "Subregister index out of bounds");
378 LaneBitmask Result;
379 for (const MaskRolOp *Ops =
380 &LaneMaskComposeSequences[CompositeSequences[IdxA]];
381 Ops->Mask.any(); ++Ops) {
382 LaneBitmask::Type M = LaneMask.getAsInteger() & Ops->Mask.getAsInteger();
383 if (unsigned S = Ops->RotateLeft)
384 Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - S)));
385 else
386 Result |= LaneBitmask(M);
387 }
388 return Result;
389}
390
391LaneBitmask LoongArchGenRegisterInfo::reverseComposeSubRegIndexLaneMaskImpl(unsigned IdxA, LaneBitmask LaneMask) const {
392 LaneMask &= getSubRegIndexLaneMask(SubIdx: IdxA);
393 --IdxA; assert(IdxA < 3 && "Subregister index out of bounds");
394 LaneBitmask Result;
395 for (const MaskRolOp *Ops =
396 &LaneMaskComposeSequences[CompositeSequences[IdxA]];
397 Ops->Mask.any(); ++Ops) {
398 LaneBitmask::Type M = LaneMask.getAsInteger();
399 if (unsigned S = Ops->RotateLeft)
400 Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - S)));
401 else
402 Result |= LaneBitmask(M);
403 }
404 return Result;
405}
406
407const TargetRegisterClass *LoongArchGenRegisterInfo::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const {
408 static constexpr uint8_t Table[11][3] = {
409 { // FPR32
410 0, // sub_32
411 0, // sub_64
412 0, // sub_128
413 },
414 { // GPR
415 0, // sub_32
416 0, // sub_64
417 0, // sub_128
418 },
419 { // GPRJR
420 0, // sub_32
421 0, // sub_64
422 0, // sub_128
423 },
424 { // GPRNoR0R1
425 0, // sub_32
426 0, // sub_64
427 0, // sub_128
428 },
429 { // GPRT
430 0, // sub_32
431 0, // sub_64
432 0, // sub_128
433 },
434 { // CFR
435 0, // sub_32
436 0, // sub_64
437 0, // sub_128
438 },
439 { // FCSR
440 0, // sub_32
441 0, // sub_64
442 0, // sub_128
443 },
444 { // SCR
445 0, // sub_32
446 0, // sub_64
447 0, // sub_128
448 },
449 { // FPR64
450 9, // sub_32 -> FPR64
451 0, // sub_64
452 0, // sub_128
453 },
454 { // LSX128
455 10, // sub_32 -> LSX128
456 10, // sub_64 -> LSX128
457 0, // sub_128
458 },
459 { // LASX256
460 11, // sub_32 -> LASX256
461 11, // sub_64 -> LASX256
462 11, // sub_128 -> LASX256
463 },
464
465 };
466 assert(RC && "Missing regclass");
467 if (!Idx) return RC;
468 --Idx;
469 assert(Idx < 3 && "Bad subreg");
470 unsigned TV = Table[RC->getID()][Idx];
471 return TV ? getRegClass(i: TV - 1) : nullptr;
472}const TargetRegisterClass *LoongArchGenRegisterInfo::getSubRegisterClass(const TargetRegisterClass *RC, unsigned Idx) const {
473 static constexpr uint8_t Table[11][3] = {
474 { // FPR32
475 0, // FPR32:sub_32
476 0, // FPR32:sub_64
477 0, // FPR32:sub_128
478 },
479 { // GPR
480 0, // GPR:sub_32
481 0, // GPR:sub_64
482 0, // GPR:sub_128
483 },
484 { // GPRJR
485 0, // GPRJR:sub_32
486 0, // GPRJR:sub_64
487 0, // GPRJR:sub_128
488 },
489 { // GPRNoR0R1
490 0, // GPRNoR0R1:sub_32
491 0, // GPRNoR0R1:sub_64
492 0, // GPRNoR0R1:sub_128
493 },
494 { // GPRT
495 0, // GPRT:sub_32
496 0, // GPRT:sub_64
497 0, // GPRT:sub_128
498 },
499 { // CFR
500 0, // CFR:sub_32
501 0, // CFR:sub_64
502 0, // CFR:sub_128
503 },
504 { // FCSR
505 0, // FCSR:sub_32
506 0, // FCSR:sub_64
507 0, // FCSR:sub_128
508 },
509 { // SCR
510 0, // SCR:sub_32
511 0, // SCR:sub_64
512 0, // SCR:sub_128
513 },
514 { // FPR64
515 1, // FPR64:sub_32 -> FPR32
516 0, // FPR64:sub_64
517 0, // FPR64:sub_128
518 },
519 { // LSX128
520 1, // LSX128:sub_32 -> FPR32
521 9, // LSX128:sub_64 -> FPR64
522 0, // LSX128:sub_128
523 },
524 { // LASX256
525 1, // LASX256:sub_32 -> FPR32
526 9, // LASX256:sub_64 -> FPR64
527 10, // LASX256:sub_128 -> LSX128
528 },
529
530 };
531 assert(RC && "Missing regclass");
532 if (!Idx) return RC;
533 --Idx;
534 assert(Idx < 3 && "Bad subreg");
535 unsigned TV = Table[RC->getID()][Idx];
536 return TV ? getRegClass(i: TV - 1) : nullptr;
537}/// Get the weight in units of pressure for this register class.
538const RegClassWeight &LoongArchGenRegisterInfo::
539getRegClassWeight(const TargetRegisterClass *RC) const {
540 static const RegClassWeight RCWeightTable[] = {
541 {.RegWeight: 1, .WeightLimit: 32}, // FPR32
542 {.RegWeight: 1, .WeightLimit: 32}, // GPR
543 {.RegWeight: 1, .WeightLimit: 31}, // GPRJR
544 {.RegWeight: 1, .WeightLimit: 30}, // GPRNoR0R1
545 {.RegWeight: 1, .WeightLimit: 17}, // GPRT
546 {.RegWeight: 1, .WeightLimit: 8}, // CFR
547 {.RegWeight: 0, .WeightLimit: 0}, // FCSR
548 {.RegWeight: 0, .WeightLimit: 0}, // SCR
549 {.RegWeight: 1, .WeightLimit: 32}, // FPR64
550 {.RegWeight: 1, .WeightLimit: 32}, // LSX128
551 {.RegWeight: 1, .WeightLimit: 32}, // LASX256
552 };
553 return RCWeightTable[RC->getID()];
554}
555
556/// Get the weight in units of pressure for this register unit.
557unsigned LoongArchGenRegisterInfo::
558getRegUnitWeight(MCRegUnit RegUnit) const {
559 assert(static_cast<unsigned>(RegUnit) < 80 && "invalid register unit");
560 // All register units have unit weight.
561 return 1;
562}
563
564
565// Get the number of dimensions of register pressure.
566unsigned LoongArchGenRegisterInfo::getNumRegPressureSets() const {
567 return 4;
568}
569
570// Get the name of this register unit pressure set.
571const char *LoongArchGenRegisterInfo::
572getRegPressureSetName(unsigned Idx) const {
573 static const char *PressureNameTable[] = {
574 "CFR",
575 "GPRT",
576 "FPR32",
577 "GPR",
578 };
579 return PressureNameTable[Idx];
580}
581
582// Get the register unit pressure limit for this dimension.
583// This limit must be adjusted dynamically for reserved registers.
584unsigned LoongArchGenRegisterInfo::
585getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const {
586 static const uint8_t PressureLimitTable[] = {
587 8, // 0: CFR
588 17, // 1: GPRT
589 32, // 2: FPR32
590 32, // 3: GPR
591 };
592 return PressureLimitTable[Idx];
593}
594
595/// Table of pressure sets per register class or unit.
596static const int RCSetsTable[] = {
597 /* 0 */ 0, -1,
598 /* 2 */ 2, -1,
599 /* 4 */ 1, 3, -1,
600};
601
602/// Get the dimensions of register pressure impacted by this register class.
603/// Returns a -1 terminated array of pressure set IDs
604const int *LoongArchGenRegisterInfo::
605getRegClassPressureSets(const TargetRegisterClass *RC) const {
606 static const uint8_t RCSetStartTable[] = {
607 2,5,5,5,4,0,1,1,2,2,2,};
608 return &RCSetsTable[RCSetStartTable[RC->getID()]];
609}
610
611/// Get the dimensions of register pressure impacted by this register unit.
612/// Returns a -1 terminated array of pressure set IDs
613const int *LoongArchGenRegisterInfo::
614getRegUnitPressureSets(MCRegUnit RegUnit) const {
615 assert(static_cast<unsigned>(RegUnit) < 80 && "invalid register unit");
616 static const uint8_t RUSetStartTable[] = {
617 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,};
618 return &RCSetsTable[RUSetStartTable[static_cast<unsigned>(RegUnit)]];
619}
620
621extern const MCRegisterDesc LoongArchRegDesc[];
622extern const int16_t LoongArchRegDiffLists[];
623extern const LaneBitmask LoongArchLaneMaskLists[];
624extern const char LoongArchRegStrings[];
625extern const char LoongArchRegClassStrings[];
626extern const MCPhysReg LoongArchRegUnitRoots[][2];
627extern const uint16_t LoongArchSubRegIdxLists[];
628extern const uint16_t LoongArchRegEncodingTable[];
629// LoongArch Dwarf<->LLVM register mappings.
630extern const MCRegisterInfo::DwarfLLVMRegPair LoongArchDwarfFlavour0Dwarf2L[];
631extern const unsigned LoongArchDwarfFlavour0Dwarf2LSize;
632
633extern const MCRegisterInfo::DwarfLLVMRegPair LoongArchEHFlavour0Dwarf2L[];
634extern const unsigned LoongArchEHFlavour0Dwarf2LSize;
635
636extern const MCRegisterInfo::DwarfLLVMRegPair LoongArchDwarfFlavour0L2Dwarf[];
637extern const unsigned LoongArchDwarfFlavour0L2DwarfSize;
638
639extern const MCRegisterInfo::DwarfLLVMRegPair LoongArchEHFlavour0L2Dwarf[];
640extern const unsigned LoongArchEHFlavour0L2DwarfSize;
641
642
643LoongArchGenRegisterInfo::
644LoongArchGenRegisterInfo(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,
645 unsigned PC, unsigned HwMode)
646 : TargetRegisterInfo(&LoongArchRegInfoDesc, LoongArchRegisterClasses,
647 LoongArchSubRegIndexStrings, LoongArchSubRegIndexNameOffsets,
648 LoongArchSubRegIdxRangeTable, LoongArchSubRegIndexLaneMaskTable,
649
650 LaneBitmask(0xFFFFFFFFFFFFFFFE), LoongArchRegClassInfos, LoongArchVTLists, HwMode) {
651 InitMCRegisterInfo(D: LoongArchRegDesc, NR: 177, RA, PC,
652 C: LoongArchMCRegisterClasses, NC: 11, RURoots: LoongArchRegUnitRoots, NRU: 80, DL: LoongArchRegDiffLists,
653 RUMS: LoongArchLaneMaskLists, Strings: LoongArchRegStrings, ClassStrings: LoongArchRegClassStrings, SubIndices: LoongArchSubRegIdxLists, NumIndices: 4,
654 RET: LoongArchRegEncodingTable, RUI: nullptr);
655
656 switch (DwarfFlavour) {
657 default:
658 llvm_unreachable("Unknown DWARF flavour");
659 case 0:
660 mapDwarfRegsToLLVMRegs(Map: LoongArchDwarfFlavour0Dwarf2L, Size: LoongArchDwarfFlavour0Dwarf2LSize, isEH: false);
661 break;
662 }
663 switch (EHFlavour) {
664 default:
665 llvm_unreachable("Unknown DWARF flavour");
666 case 0:
667 mapDwarfRegsToLLVMRegs(Map: LoongArchEHFlavour0Dwarf2L, Size: LoongArchEHFlavour0Dwarf2LSize, isEH: true);
668 break;
669 }
670 switch (DwarfFlavour) {
671 default:
672 llvm_unreachable("Unknown DWARF flavour");
673 case 0:
674 mapLLVMRegsToDwarfRegs(Map: LoongArchDwarfFlavour0L2Dwarf, Size: LoongArchDwarfFlavour0L2DwarfSize, isEH: false);
675 break;
676 }
677 switch (EHFlavour) {
678 default:
679 llvm_unreachable("Unknown DWARF flavour");
680 case 0:
681 mapLLVMRegsToDwarfRegs(Map: LoongArchEHFlavour0L2Dwarf, Size: LoongArchEHFlavour0L2DwarfSize, isEH: true);
682 break;
683 }
684}
685
686static 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 };
687static const uint32_t CSR_ILP32D_LP64D_RegMask[] = { 0xfe000000, 0x00006001, 0x00001ff8, 0x00000000, 0x00000000, 0x0001fe00, };
688static 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 };
689static const uint32_t CSR_ILP32F_LP64F_RegMask[] = { 0xfe000000, 0x00006001, 0x00001ff8, 0x00000000, 0x00000000, 0x00000000, };
690static 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 };
691static const uint32_t CSR_ILP32S_LP64S_RegMask[] = { 0x00000000, 0x00006000, 0x00001ff8, 0x00000000, 0x00000000, 0x00000000, };
692static 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 };
693static const uint32_t CSR_MostRegs_RegMask[] = { 0x00000000, 0xe1fe6000, 0x00001ff9, 0x00000000, 0x00000000, 0x00000000, };
694static const MCPhysReg CSR_NoRegs_SaveList[] = { 0 };
695static const uint32_t CSR_NoRegs_RegMask[] = { 0x00000000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, };
696static const MCPhysReg CSR_NoneRegs_SaveList[] = { LoongArch::R1, LoongArch::R22, 0 };
697static const uint32_t CSR_NoneRegs_RegMask[] = { 0x00000000, 0x00006000, 0x00000008, 0x00000000, 0x00000000, 0x00000000, };
698
699
700ArrayRef<const uint32_t *> LoongArchGenRegisterInfo::getRegMasks() const {
701 static const uint32_t *const Masks[] = {
702 CSR_ILP32D_LP64D_RegMask,
703 CSR_ILP32F_LP64F_RegMask,
704 CSR_ILP32S_LP64S_RegMask,
705 CSR_MostRegs_RegMask,
706 CSR_NoRegs_RegMask,
707 CSR_NoneRegs_RegMask,
708 };
709 return ArrayRef(Masks);
710}
711
712bool LoongArchGenRegisterInfo::
713isGeneralPurposeRegister(const MachineFunction &MF, MCRegister PhysReg) const {
714 return
715 false;
716}
717
718bool LoongArchGenRegisterInfo::
719isGeneralPurposeRegisterClass(const TargetRegisterClass *RC) const {
720 return
721 false;
722}
723
724bool LoongArchGenRegisterInfo::
725isFixedRegister(const MachineFunction &MF, MCRegister PhysReg) const {
726 return
727 false;
728}
729
730bool LoongArchGenRegisterInfo::
731isArgumentRegister(const MachineFunction &MF, MCRegister PhysReg) const {
732 return
733 false;
734}
735
736bool LoongArchGenRegisterInfo::
737isConstantPhysReg(MCRegister PhysReg) const {
738 return
739 PhysReg == LoongArch::R0 ||
740 false;
741}
742
743ArrayRef<const char *> LoongArchGenRegisterInfo::getRegMaskNames() const {
744 static const char *Names[] = {
745 "CSR_ILP32D_LP64D",
746 "CSR_ILP32F_LP64F",
747 "CSR_ILP32S_LP64S",
748 "CSR_MostRegs",
749 "CSR_NoRegs",
750 "CSR_NoneRegs",
751 };
752 return ArrayRef(Names);
753}
754
755const LoongArchFrameLowering *
756LoongArchGenRegisterInfo::getFrameLowering(const MachineFunction &MF) {
757 return static_cast<const LoongArchFrameLowering *>(
758 MF.getSubtarget().getFrameLowering());
759}
760
761
762} // namespace llvm
763