LLVM 23.0.0git
AArch64BaseInfo.h
Go to the documentation of this file.
1//===-- AArch64BaseInfo.h - Top level definitions for AArch64 ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains small standalone helper functions and enum definitions for
10// the AArch64 target useful for the compiler back-end and the MC libraries.
11// As such, it deliberately does not include references to LLVM core
12// code gen types, passes, etc..
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64BASEINFO_H
17#define LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64BASEINFO_H
18
19// FIXME: Is it easiest to fix this layering violation by moving the .inc
20// #includes from AArch64MCTargetDesc.h to here?
21#include "MCTargetDesc/AArch64MCTargetDesc.h" // For AArch64::X0 and friends.
22#include "llvm/ADT/APFloat.h"
23#include "llvm/ADT/APSInt.h"
25#include "llvm/ADT/STLExtras.h"
30
31namespace llvm {
32
34 switch (Reg.id()) {
35 case AArch64::X0: return AArch64::W0;
36 case AArch64::X1: return AArch64::W1;
37 case AArch64::X2: return AArch64::W2;
38 case AArch64::X3: return AArch64::W3;
39 case AArch64::X4: return AArch64::W4;
40 case AArch64::X5: return AArch64::W5;
41 case AArch64::X6: return AArch64::W6;
42 case AArch64::X7: return AArch64::W7;
43 case AArch64::X8: return AArch64::W8;
44 case AArch64::X9: return AArch64::W9;
45 case AArch64::X10: return AArch64::W10;
46 case AArch64::X11: return AArch64::W11;
47 case AArch64::X12: return AArch64::W12;
48 case AArch64::X13: return AArch64::W13;
49 case AArch64::X14: return AArch64::W14;
50 case AArch64::X15: return AArch64::W15;
51 case AArch64::X16: return AArch64::W16;
52 case AArch64::X17: return AArch64::W17;
53 case AArch64::X18: return AArch64::W18;
54 case AArch64::X19: return AArch64::W19;
55 case AArch64::X20: return AArch64::W20;
56 case AArch64::X21: return AArch64::W21;
57 case AArch64::X22: return AArch64::W22;
58 case AArch64::X23: return AArch64::W23;
59 case AArch64::X24: return AArch64::W24;
60 case AArch64::X25: return AArch64::W25;
61 case AArch64::X26: return AArch64::W26;
62 case AArch64::X27: return AArch64::W27;
63 case AArch64::X28: return AArch64::W28;
64 case AArch64::FP: return AArch64::W29;
65 case AArch64::LR: return AArch64::W30;
66 case AArch64::SP: return AArch64::WSP;
67 case AArch64::XZR: return AArch64::WZR;
68 }
69 // For anything else, return it unchanged.
70 return Reg;
71}
72
74 switch (Reg.id()) {
75 case AArch64::W0: return AArch64::X0;
76 case AArch64::W1: return AArch64::X1;
77 case AArch64::W2: return AArch64::X2;
78 case AArch64::W3: return AArch64::X3;
79 case AArch64::W4: return AArch64::X4;
80 case AArch64::W5: return AArch64::X5;
81 case AArch64::W6: return AArch64::X6;
82 case AArch64::W7: return AArch64::X7;
83 case AArch64::W8: return AArch64::X8;
84 case AArch64::W9: return AArch64::X9;
85 case AArch64::W10: return AArch64::X10;
86 case AArch64::W11: return AArch64::X11;
87 case AArch64::W12: return AArch64::X12;
88 case AArch64::W13: return AArch64::X13;
89 case AArch64::W14: return AArch64::X14;
90 case AArch64::W15: return AArch64::X15;
91 case AArch64::W16: return AArch64::X16;
92 case AArch64::W17: return AArch64::X17;
93 case AArch64::W18: return AArch64::X18;
94 case AArch64::W19: return AArch64::X19;
95 case AArch64::W20: return AArch64::X20;
96 case AArch64::W21: return AArch64::X21;
97 case AArch64::W22: return AArch64::X22;
98 case AArch64::W23: return AArch64::X23;
99 case AArch64::W24: return AArch64::X24;
100 case AArch64::W25: return AArch64::X25;
101 case AArch64::W26: return AArch64::X26;
102 case AArch64::W27: return AArch64::X27;
103 case AArch64::W28: return AArch64::X28;
104 case AArch64::W29: return AArch64::FP;
105 case AArch64::W30: return AArch64::LR;
106 case AArch64::WSP: return AArch64::SP;
107 case AArch64::WZR: return AArch64::XZR;
108 }
109 // For anything else, return it unchanged.
110 return Reg;
111}
112
114 switch (RegTuple.id()) {
115 case AArch64::X0_X1_X2_X3_X4_X5_X6_X7: return AArch64::X0;
116 case AArch64::X2_X3_X4_X5_X6_X7_X8_X9: return AArch64::X2;
117 case AArch64::X4_X5_X6_X7_X8_X9_X10_X11: return AArch64::X4;
118 case AArch64::X6_X7_X8_X9_X10_X11_X12_X13: return AArch64::X6;
119 case AArch64::X8_X9_X10_X11_X12_X13_X14_X15: return AArch64::X8;
120 case AArch64::X10_X11_X12_X13_X14_X15_X16_X17: return AArch64::X10;
121 case AArch64::X12_X13_X14_X15_X16_X17_X18_X19: return AArch64::X12;
122 case AArch64::X14_X15_X16_X17_X18_X19_X20_X21: return AArch64::X14;
123 case AArch64::X16_X17_X18_X19_X20_X21_X22_X23: return AArch64::X16;
124 case AArch64::X18_X19_X20_X21_X22_X23_X24_X25: return AArch64::X18;
125 case AArch64::X20_X21_X22_X23_X24_X25_X26_X27: return AArch64::X20;
126 case AArch64::X22_X23_X24_X25_X26_X27_X28_FP: return AArch64::X22;
127 }
128 // For anything else, return it unchanged.
129 return RegTuple;
130}
131
133 switch (Reg.id()) {
134 case AArch64::D0: return AArch64::B0;
135 case AArch64::D1: return AArch64::B1;
136 case AArch64::D2: return AArch64::B2;
137 case AArch64::D3: return AArch64::B3;
138 case AArch64::D4: return AArch64::B4;
139 case AArch64::D5: return AArch64::B5;
140 case AArch64::D6: return AArch64::B6;
141 case AArch64::D7: return AArch64::B7;
142 case AArch64::D8: return AArch64::B8;
143 case AArch64::D9: return AArch64::B9;
144 case AArch64::D10: return AArch64::B10;
145 case AArch64::D11: return AArch64::B11;
146 case AArch64::D12: return AArch64::B12;
147 case AArch64::D13: return AArch64::B13;
148 case AArch64::D14: return AArch64::B14;
149 case AArch64::D15: return AArch64::B15;
150 case AArch64::D16: return AArch64::B16;
151 case AArch64::D17: return AArch64::B17;
152 case AArch64::D18: return AArch64::B18;
153 case AArch64::D19: return AArch64::B19;
154 case AArch64::D20: return AArch64::B20;
155 case AArch64::D21: return AArch64::B21;
156 case AArch64::D22: return AArch64::B22;
157 case AArch64::D23: return AArch64::B23;
158 case AArch64::D24: return AArch64::B24;
159 case AArch64::D25: return AArch64::B25;
160 case AArch64::D26: return AArch64::B26;
161 case AArch64::D27: return AArch64::B27;
162 case AArch64::D28: return AArch64::B28;
163 case AArch64::D29: return AArch64::B29;
164 case AArch64::D30: return AArch64::B30;
165 case AArch64::D31: return AArch64::B31;
166 }
167 // For anything else, return it unchanged.
168 return Reg;
169}
170
172 switch (Reg.id()) {
173 case AArch64::B0: return AArch64::D0;
174 case AArch64::B1: return AArch64::D1;
175 case AArch64::B2: return AArch64::D2;
176 case AArch64::B3: return AArch64::D3;
177 case AArch64::B4: return AArch64::D4;
178 case AArch64::B5: return AArch64::D5;
179 case AArch64::B6: return AArch64::D6;
180 case AArch64::B7: return AArch64::D7;
181 case AArch64::B8: return AArch64::D8;
182 case AArch64::B9: return AArch64::D9;
183 case AArch64::B10: return AArch64::D10;
184 case AArch64::B11: return AArch64::D11;
185 case AArch64::B12: return AArch64::D12;
186 case AArch64::B13: return AArch64::D13;
187 case AArch64::B14: return AArch64::D14;
188 case AArch64::B15: return AArch64::D15;
189 case AArch64::B16: return AArch64::D16;
190 case AArch64::B17: return AArch64::D17;
191 case AArch64::B18: return AArch64::D18;
192 case AArch64::B19: return AArch64::D19;
193 case AArch64::B20: return AArch64::D20;
194 case AArch64::B21: return AArch64::D21;
195 case AArch64::B22: return AArch64::D22;
196 case AArch64::B23: return AArch64::D23;
197 case AArch64::B24: return AArch64::D24;
198 case AArch64::B25: return AArch64::D25;
199 case AArch64::B26: return AArch64::D26;
200 case AArch64::B27: return AArch64::D27;
201 case AArch64::B28: return AArch64::D28;
202 case AArch64::B29: return AArch64::D29;
203 case AArch64::B30: return AArch64::D30;
204 case AArch64::B31: return AArch64::D31;
205 }
206 // For anything else, return it unchanged.
207 return Reg;
208}
209
210static inline bool atomicBarrierDroppedOnZero(unsigned Opcode) {
211 switch (Opcode) {
212 case AArch64::LDADDAB: case AArch64::LDADDAH:
213 case AArch64::LDADDAW: case AArch64::LDADDAX:
214 case AArch64::LDADDALB: case AArch64::LDADDALH:
215 case AArch64::LDADDALW: case AArch64::LDADDALX:
216 case AArch64::LDCLRAB: case AArch64::LDCLRAH:
217 case AArch64::LDCLRAW: case AArch64::LDCLRAX:
218 case AArch64::LDCLRALB: case AArch64::LDCLRALH:
219 case AArch64::LDCLRALW: case AArch64::LDCLRALX:
220 case AArch64::LDEORAB: case AArch64::LDEORAH:
221 case AArch64::LDEORAW: case AArch64::LDEORAX:
222 case AArch64::LDEORALB: case AArch64::LDEORALH:
223 case AArch64::LDEORALW: case AArch64::LDEORALX:
224 case AArch64::LDSETAB: case AArch64::LDSETAH:
225 case AArch64::LDSETAW: case AArch64::LDSETAX:
226 case AArch64::LDSETALB: case AArch64::LDSETALH:
227 case AArch64::LDSETALW: case AArch64::LDSETALX:
228 case AArch64::LDSMAXAB: case AArch64::LDSMAXAH:
229 case AArch64::LDSMAXAW: case AArch64::LDSMAXAX:
230 case AArch64::LDSMAXALB: case AArch64::LDSMAXALH:
231 case AArch64::LDSMAXALW: case AArch64::LDSMAXALX:
232 case AArch64::LDSMINAB: case AArch64::LDSMINAH:
233 case AArch64::LDSMINAW: case AArch64::LDSMINAX:
234 case AArch64::LDSMINALB: case AArch64::LDSMINALH:
235 case AArch64::LDSMINALW: case AArch64::LDSMINALX:
236 case AArch64::LDUMAXAB: case AArch64::LDUMAXAH:
237 case AArch64::LDUMAXAW: case AArch64::LDUMAXAX:
238 case AArch64::LDUMAXALB: case AArch64::LDUMAXALH:
239 case AArch64::LDUMAXALW: case AArch64::LDUMAXALX:
240 case AArch64::LDUMINAB: case AArch64::LDUMINAH:
241 case AArch64::LDUMINAW: case AArch64::LDUMINAX:
242 case AArch64::LDUMINALB: case AArch64::LDUMINALH:
243 case AArch64::LDUMINALW: case AArch64::LDUMINALX:
244 case AArch64::SWPAB: case AArch64::SWPAH:
245 case AArch64::SWPAW: case AArch64::SWPAX:
246 case AArch64::SWPALB: case AArch64::SWPALH:
247 case AArch64::SWPALW: case AArch64::SWPALX:
248 return true;
249 }
250 return false;
251}
252
253inline unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth,
254 bool isReciprocal) {
255 // An FCVT[SU] instruction performs: convertToInt(Val * 2^fbits) where fbits
256 // is between 1 and 32 for a destination w-register, or 1 and 64 for an
257 // x-register.
258 //
259 // By this stage, we've detected (fp_to_[su]int (fmul Val, THIS_NODE)) so we
260 // want THIS_NODE to be 2^fbits. This is much easier to deal with using
261 // integers.
262 bool IsExact;
263
264 if (isReciprocal)
265 if (!FVal.getExactInverse(&FVal))
266 return 0;
267
268 // fbits is between 1 and 64 in the worst-case, which means the fmul
269 // could have 2^64 as an actual operand. Need 65 bits of precision.
270 APSInt IntVal(65, true);
271 FVal.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact);
272
273 // N.b. isPowerOf2 also checks for > 0.
274 if (!IsExact || !IntVal.isPowerOf2())
275 return 0;
276 unsigned FBits = IntVal.logBase2();
277
278 // Checks above should have guaranteed that we haven't lost information in
279 // finding FBits, but it must still be in range.
280 if (FBits == 0 || FBits > RegWidth)
281 return 0;
282 return FBits;
283}
284
285namespace AArch64CC {
286
287// The CondCodes constants map directly to the 4-bit encoding of the condition
288// field for predicated instructions.
289enum CondCode { // Meaning (integer) Meaning (floating-point)
290 EQ = 0x0, // Equal Equal
291 NE = 0x1, // Not equal Not equal, or unordered
292 HS = 0x2, // Unsigned higher or same >, ==, or unordered
293 LO = 0x3, // Unsigned lower Less than
294 MI = 0x4, // Minus, negative Less than
295 PL = 0x5, // Plus, positive or zero >, ==, or unordered
296 VS = 0x6, // Overflow Unordered
297 VC = 0x7, // No overflow Not unordered
298 HI = 0x8, // Unsigned higher Greater than, or unordered
299 LS = 0x9, // Unsigned lower or same Less than or equal
300 GE = 0xa, // Greater than or equal Greater than or equal
301 LT = 0xb, // Less than Less than, or unordered
302 GT = 0xc, // Greater than Greater than
303 LE = 0xd, // Less than or equal <, ==, or unordered
304 AL = 0xe, // Always (unconditional) Always (unconditional)
305 NV = 0xf, // Always (unconditional) Always (unconditional)
306 // Note the NV exists purely to disassemble 0b1111. Execution is "always".
308
309 // Common aliases used for SVE.
310 ANY_ACTIVE = NE, // (!Z)
311 FIRST_ACTIVE = MI, // ( N)
312 LAST_ACTIVE = LO, // (!C)
313 NONE_ACTIVE = EQ // ( Z)
314};
315
316inline static const char *getCondCodeName(CondCode Code) {
317 switch (Code) {
318 default: llvm_unreachable("Unknown condition code");
319 case EQ: return "eq";
320 case NE: return "ne";
321 case HS: return "hs";
322 case LO: return "lo";
323 case MI: return "mi";
324 case PL: return "pl";
325 case VS: return "vs";
326 case VC: return "vc";
327 case HI: return "hi";
328 case LS: return "ls";
329 case GE: return "ge";
330 case LT: return "lt";
331 case GT: return "gt";
332 case LE: return "le";
333 case AL: return "al";
334 case NV: return "nv";
335 }
336}
337
339 // To reverse a condition it's necessary to only invert the low bit:
340
341 return static_cast<CondCode>(static_cast<unsigned>(Code) ^ 0x1);
342}
343
344/// getSwappedCondition - assume the flags are set by MI(a,b), return
345/// the condition code if we modify the instructions such that flags are
346/// set by MI(b,a).
348 switch (CC) {
349 default:
350 return AL;
351 case EQ:
352 return EQ;
353 case NE:
354 return NE;
355 case HS:
356 return LS;
357 case LO:
358 return HI;
359 case HI:
360 return LO;
361 case LS:
362 return HS;
363 case GE:
364 return LE;
365 case LT:
366 return GT;
367 case GT:
368 return LT;
369 case LE:
370 return GE;
371 }
372}
373
374/// Given a condition code, return NZCV flags that would satisfy that condition.
375/// The flag bits are in the format expected by the ccmp instructions.
376/// Note that many different flag settings can satisfy a given condition code,
377/// this function just returns one of them.
378inline static unsigned getNZCVToSatisfyCondCode(CondCode Code) {
379 // NZCV flags encoded as expected by ccmp instructions, ARMv8 ISA 5.5.7.
380 enum { N = 8, Z = 4, C = 2, V = 1 };
381 switch (Code) {
382 default: llvm_unreachable("Unknown condition code");
383 case EQ: return Z; // Z == 1
384 case NE: return 0; // Z == 0
385 case HS: return C; // C == 1
386 case LO: return 0; // C == 0
387 case MI: return N; // N == 1
388 case PL: return 0; // N == 0
389 case VS: return V; // V == 1
390 case VC: return 0; // V == 0
391 case HI: return C; // C == 1 && Z == 0
392 case LS: return 0; // C == 0 || Z == 1
393 case GE: return 0; // N == V
394 case LT: return N; // N != V
395 case GT: return 0; // Z == 0 && N == V
396 case LE: return Z; // Z == 1 || N != V
397 }
398}
399
400/// True, if a given condition code can be used in a fused compare-and-branch
401/// instructions, false otherwise.
402inline static bool isValidCBCond(AArch64CC::CondCode Code) {
403 switch (Code) {
404 default:
405 return false;
406 case AArch64CC::EQ:
407 case AArch64CC::NE:
408 case AArch64CC::HS:
409 case AArch64CC::LO:
410 case AArch64CC::HI:
411 case AArch64CC::LS:
412 case AArch64CC::GE:
413 case AArch64CC::LT:
414 case AArch64CC::GT:
415 case AArch64CC::LE:
416 return true;
417 }
418}
419
420} // end namespace AArch64CC
421
422struct SysAlias {
426
431
432 bool haveFeatures(FeatureBitset ActiveFeatures) const {
433 return ActiveFeatures[llvm::AArch64::FeatureAll] ||
434 (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
435 }
436
438};
439
440#define GET_SysAliasRegUse_DECL
441#include "AArch64GenSystemOperands.inc"
442
446 : SysAlias(N, E), NeedsReg(R) {}
449 : SysAlias(N, E, F), NeedsReg(R) {}
450};
451
453 SysAliasRegUse RegUse;
455 SysAliasRegUse R)
456 : SysAlias(N, E), RegUse(R) {}
458 SysAliasRegUse R, FeatureBitset F)
459 : SysAlias(N, E, F), RegUse(R) {}
460};
461
464
468
469 bool haveFeatures(FeatureBitset ActiveFeatures) const {
470 return SysAliasOptionalReg::haveFeatures(ActiveFeatures) &&
471 (ActiveFeatures[llvm::AArch64::FeatureAll] ||
472 ActiveFeatures[llvm::AArch64::FeatureD128] ||
473 (AllowWithTLBID && ActiveFeatures[llvm::AArch64::FeatureTLBID]));
474 }
475};
476
485
486namespace AArch64SVCR {
487 struct SVCR : SysAlias{
488 using SysAlias::SysAlias;
489 };
490#define GET_SVCRValues_DECL
491#define GET_SVCRsList_DECL
492#include "AArch64GenSystemOperands.inc"
493}
494
495namespace AArch64AT{
496 struct AT : SysAlias {
497 using SysAlias::SysAlias;
498 };
499#define GET_ATValues_DECL
500#define GET_ATsList_DECL
501#include "AArch64GenSystemOperands.inc"
502}
503
504namespace AArch64DB {
505 struct DB : SysAlias {
506 using SysAlias::SysAlias;
507 };
508#define GET_DBValues_DECL
509#define GET_DBsList_DECL
510#include "AArch64GenSystemOperands.inc"
511}
512
513namespace AArch64DBnXS {
516 };
517#define GET_DBnXSValues_DECL
518#define GET_DBnXSsList_DECL
519#include "AArch64GenSystemOperands.inc"
520}
521
522namespace AArch64DC {
523 struct DC : SysAlias {
524 using SysAlias::SysAlias;
525 };
526#define GET_DCValues_DECL
527#define GET_DCsList_DECL
528#include "AArch64GenSystemOperands.inc"
529}
530
531namespace AArch64IC {
532 struct IC : SysAliasReg {
534 };
535#define GET_ICValues_DECL
536#define GET_ICsList_DECL
537#include "AArch64GenSystemOperands.inc"
538}
539
540namespace AArch64ISB {
541 struct ISB : SysAlias {
542 using SysAlias::SysAlias;
543 };
544#define GET_ISBValues_DECL
545#define GET_ISBsList_DECL
546#include "AArch64GenSystemOperands.inc"
547}
548
549namespace AArch64PRFM {
550 struct PRFM : SysAlias {
551 using SysAlias::SysAlias;
552 };
553#define GET_PRFMValues_DECL
554#define GET_PRFMsList_DECL
555#include "AArch64GenSystemOperands.inc"
556}
557
558namespace AArch64SVEPRFM {
559 struct SVEPRFM : SysAlias {
560 using SysAlias::SysAlias;
561 };
562#define GET_SVEPRFMValues_DECL
563#define GET_SVEPRFMsList_DECL
564#include "AArch64GenSystemOperands.inc"
565}
566
567namespace AArch64RPRFM {
568struct RPRFM : SysAlias {
569 using SysAlias::SysAlias;
570};
571#define GET_RPRFMValues_DECL
572#define GET_RPRFMsList_DECL
573#include "AArch64GenSystemOperands.inc"
574} // namespace AArch64RPRFM
575
576namespace AArch64SVEPredPattern {
581#define GET_SVEPREDPATValues_DECL
582#define GET_SVEPREDPATsList_DECL
583#include "AArch64GenSystemOperands.inc"
584}
585
591#define GET_SVEVECLENSPECIFIERValues_DECL
592#define GET_SVEVECLENSPECIFIERsList_DECL
593#include "AArch64GenSystemOperands.inc"
594} // namespace AArch64SVEVecLenSpecifier
595
596/// Return the number of active elements for VL1 to VL256 predicate pattern,
597/// zero for all other patterns.
598inline unsigned getNumElementsFromSVEPredPattern(unsigned Pattern) {
599 switch (Pattern) {
600 default:
601 return 0;
602 case AArch64SVEPredPattern::vl1:
603 case AArch64SVEPredPattern::vl2:
604 case AArch64SVEPredPattern::vl3:
605 case AArch64SVEPredPattern::vl4:
606 case AArch64SVEPredPattern::vl5:
607 case AArch64SVEPredPattern::vl6:
608 case AArch64SVEPredPattern::vl7:
609 case AArch64SVEPredPattern::vl8:
610 return Pattern;
611 case AArch64SVEPredPattern::vl16:
612 return 16;
613 case AArch64SVEPredPattern::vl32:
614 return 32;
615 case AArch64SVEPredPattern::vl64:
616 return 64;
617 case AArch64SVEPredPattern::vl128:
618 return 128;
619 case AArch64SVEPredPattern::vl256:
620 return 256;
621 }
622}
623
624/// Return specific VL predicate pattern based on the number of elements.
625inline std::optional<unsigned>
627 switch (MinNumElts) {
628 default:
629 return std::nullopt;
630 case 1:
631 case 2:
632 case 3:
633 case 4:
634 case 5:
635 case 6:
636 case 7:
637 case 8:
638 return MinNumElts;
639 case 16:
640 return AArch64SVEPredPattern::vl16;
641 case 32:
642 return AArch64SVEPredPattern::vl32;
643 case 64:
644 return AArch64SVEPredPattern::vl64;
645 case 128:
646 return AArch64SVEPredPattern::vl128;
647 case 256:
648 return AArch64SVEPredPattern::vl256;
649 }
650}
651
652/// An enum to describe what types of loops we should attempt to tail-fold:
653/// Disabled: None
654/// Reductions: Loops containing reductions
655/// Recurrences: Loops with first-order recurrences, i.e. that would
656/// require a SVE splice instruction
657/// Reverse: Reverse loops
658/// Simple: Loops that are not reversed and don't contain reductions
659/// or first-order recurrences.
660/// All: All
669
671 /* LargestValue */ (long)TailFoldingOpts::Reverse);
672
673namespace AArch64ExactFPImm {
678#define GET_ExactFPImmValues_DECL
679#define GET_ExactFPImmsList_DECL
680#include "AArch64GenSystemOperands.inc"
681}
682
683namespace AArch64PState {
685 using SysAlias::SysAlias;
686 };
687#define GET_PStateImm0_15Values_DECL
688#define GET_PStateImm0_15sList_DECL
689#include "AArch64GenSystemOperands.inc"
690
692 using SysAlias::SysAlias;
693 };
694#define GET_PStateImm0_1Values_DECL
695#define GET_PStateImm0_1sList_DECL
696#include "AArch64GenSystemOperands.inc"
697}
698
699namespace AArch64TIndexHint {
700struct TIndex : SysAlias {
701 using SysAlias::SysAlias;
702};
703#define GET_TINDEX_DECL
704#include "AArch64GenSystemOperands.inc"
705} // namespace AArch64TIndexHint
706
714
735
736namespace AArch64Layout {
743
748
749 // Bare layout for the 128-bit vector
750 // (only show ".b", ".h", ".s", ".d" without vector number)
755 };
756}
757
758inline static const char *
760 switch (Layout) {
761 case AArch64Layout::VL_8B: return ".8b";
762 case AArch64Layout::VL_4H: return ".4h";
763 case AArch64Layout::VL_2S: return ".2s";
764 case AArch64Layout::VL_1D: return ".1d";
765 case AArch64Layout::VL_16B: return ".16b";
766 case AArch64Layout::VL_8H: return ".8h";
767 case AArch64Layout::VL_4S: return ".4s";
768 case AArch64Layout::VL_2D: return ".2d";
769 case AArch64Layout::VL_B: return ".b";
770 case AArch64Layout::VL_H: return ".h";
771 case AArch64Layout::VL_S: return ".s";
772 case AArch64Layout::VL_D: return ".d";
773 default: llvm_unreachable("Unknown Vector Layout");
774 }
775}
776
777inline static AArch64Layout::VectorLayout
794
795namespace AArch64SysReg {
796 struct SysReg {
798 unsigned Encoding;
802
803 bool haveFeatures(FeatureBitset ActiveFeatures) const {
804 return ActiveFeatures[llvm::AArch64::FeatureAll] ||
805 (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
806 }
807 };
808
809#define GET_SysRegsList_DECL
810#define GET_SysRegValues_DECL
811#include "AArch64GenSystemOperands.inc"
812
813 uint32_t parseGenericRegister(StringRef Name);
814 std::string genericRegisterString(uint32_t Bits);
815}
816
817namespace AArch64TLBI {
821#define GET_TLBITable_DECL
822#include "AArch64GenSystemOperands.inc"
823}
824
825namespace AArch64TLBIP {
829#define GET_TLBIPTable_DECL
830#include "AArch64GenSystemOperands.inc"
831} // namespace AArch64TLBIP
832
833namespace AArch64GIC {
834struct GIC : SysAliasReg {
836};
837#define GET_GICTable_DECL
838#include "AArch64GenSystemOperands.inc"
839} // namespace AArch64GIC
840
841namespace AArch64GICR {
844};
845#define GET_GICRTable_DECL
846#include "AArch64GenSystemOperands.inc"
847} // namespace AArch64GICR
848
849namespace AArch64GSB {
850struct GSB : SysAlias {
851 using SysAlias::SysAlias;
852};
853#define GET_GSBTable_DECL
854#include "AArch64GenSystemOperands.inc"
855} // namespace AArch64GSB
856
857namespace AArch64PLBI {
861#define GET_PLBITable_DECL
862#include "AArch64GenSystemOperands.inc"
863} // namespace AArch64PLBI
864
865namespace AArch64II {
866/// Target Operand Flag enum.
867enum TOF {
868 //===------------------------------------------------------------------===//
869 // AArch64 Specific MachineOperand flags.
870
872
874
875 /// MO_PAGE - A symbol operand with this flag represents the pc-relative
876 /// offset of the 4K page containing the symbol. This is used with the
877 /// ADRP instruction.
879
880 /// MO_PAGEOFF - A symbol operand with this flag represents the offset of
881 /// that symbol within a 4K page. This offset is added to the page address
882 /// to produce the complete address.
884
885 /// MO_G3 - A symbol operand with this flag (granule 3) represents the high
886 /// 16-bits of a 64-bit address, used in a MOVZ or MOVK instruction
887 MO_G3 = 3,
888
889 /// MO_G2 - A symbol operand with this flag (granule 2) represents the bits
890 /// 32-47 of a 64-bit address, used in a MOVZ or MOVK instruction
891 MO_G2 = 4,
892
893 /// MO_G1 - A symbol operand with this flag (granule 1) represents the bits
894 /// 16-31 of a 64-bit address, used in a MOVZ or MOVK instruction
895 MO_G1 = 5,
896
897 /// MO_G0 - A symbol operand with this flag (granule 0) represents the bits
898 /// 0-15 of a 64-bit address, used in a MOVZ or MOVK instruction
899 MO_G0 = 6,
900
901 /// MO_HI12 - This flag indicates that a symbol operand represents the bits
902 /// 13-24 of a 64-bit address, used in a arithmetic immediate-shifted-left-
903 /// by-12-bits instruction.
905
906 /// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
907 /// reference is actually to the ".refptr.FOO" symbol. This is used for
908 /// stub symbols on windows.
910
911 /// MO_GOT - This flag indicates that a symbol operand represents the
912 /// address of the GOT entry for the symbol, rather than the address of
913 /// the symbol itself.
914 MO_GOT = 0x10,
915
916 /// MO_NC - Indicates whether the linker is expected to check the symbol
917 /// reference for overflow. For example in an ADRP/ADD pair of relocations
918 /// the ADRP usually does check, but not the ADD.
919 MO_NC = 0x20,
920
921 /// MO_TLS - Indicates that the operand being accessed is some kind of
922 /// thread-local symbol. On Darwin, only one type of thread-local access
923 /// exists (pre linker-relaxation), but on ELF the TLSModel used for the
924 /// referee will affect interpretation.
925 MO_TLS = 0x40,
926
927 /// MO_DLLIMPORT - On a symbol operand, this represents that the reference
928 /// to the symbol is for an import stub. This is used for DLL import
929 /// storage class indication on Windows.
931
932 /// MO_S - Indicates that the bits of the symbol operand represented by
933 /// MO_G0 etc are signed.
934 MO_S = 0x100,
935
936 /// MO_PREL - Indicates that the bits of the symbol operand represented by
937 /// MO_G0 etc are PC relative.
938 MO_PREL = 0x200,
939
940 /// MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag
941 /// in bits 56-63.
942 /// On a FrameIndex operand, indicates that the underlying memory is tagged
943 /// with an unknown tag value (MTE); this needs to be lowered either to an
944 /// SP-relative load or store instruction (which do not check tags), or to
945 /// an LDG instruction to obtain the tag value.
946 MO_TAGGED = 0x400,
947
948 /// MO_ARM64EC_CALLMANGLE - Operand refers to the Arm64EC-mangled version
949 /// of a symbol, not the original. For dllimport symbols, this means it
950 /// uses "__imp_aux". For other symbols, this means it uses the mangled
951 /// ("#" prefix for C) name.
953};
954} // end namespace AArch64II
955
956//===----------------------------------------------------------------------===//
957// v8.3a Pointer Authentication
958//
959
960namespace AArch64PACKey {
961enum ID : uint8_t {
962 IA = 0,
963 IB = 1,
964 DA = 2,
965 DB = 3,
967};
968} // namespace AArch64PACKey
969
970/// Return 2-letter identifier string for numeric key ID.
972 switch (KeyID) {
974 return StringRef("ia");
976 return StringRef("ib");
978 return StringRef("da");
980 return StringRef("db");
981 }
982 llvm_unreachable("Unhandled AArch64PACKey::ID enum");
983}
984
985/// Return numeric key ID for 2-letter identifier string.
986inline static std::optional<AArch64PACKey::ID>
988 if (Name == "ia")
989 return AArch64PACKey::IA;
990 if (Name == "ib")
991 return AArch64PACKey::IB;
992 if (Name == "da")
993 return AArch64PACKey::DA;
994 if (Name == "db")
995 return AArch64PACKey::DB;
996 return std::nullopt;
997}
998
999inline static unsigned getBTIHintNum(bool CallTarget, bool JumpTarget) {
1000 unsigned HintNum = 32;
1001 if (CallTarget)
1002 HintNum |= 2;
1003 if (JumpTarget)
1004 HintNum |= 4;
1005 assert(HintNum != 32 && "No target kinds!");
1006 return HintNum;
1007}
1008
1009namespace AArch64 {
1010// The number of bits in a SVE register is architecturally defined
1011// to be a multiple of this value. If <M x t> has this number of bits,
1012// a <n x M x t> vector can be stored in a SVE register without any
1013// redundant bits. If <M x t> has this number of bits divided by P,
1014// a <n x M x t> vector is stored in a SVE register by placing index i
1015// in index i*P of a <n x (M*P) x t> vector. The other elements of the
1016// <n x (M*P) x t> vector (such as index 1) are undefined.
1017static constexpr unsigned SVEBitsPerBlock = 128;
1018static constexpr unsigned SVEMaxBitsPerVector = 2048;
1019} // end namespace AArch64
1020} // end namespace llvm
1021
1022#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
#define LLVM_DECLARE_ENUM_AS_BITMASK(Enum, LargestValue)
LLVM_DECLARE_ENUM_AS_BITMASK can be used to declare an enum type as a bit set, so that bitwise operat...
Definition BitmaskEnum.h:66
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
This file contains some templates that are useful if you are working with the STL at all.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static constexpr roundingMode rmTowardZero
Definition APFloat.h:349
LLVM_ABI bool getExactInverse(APFloat *Inv) const
If this value is normal and has an exact, normal, multiplicative inverse, store it in inv and return ...
Definition APFloat.cpp:5843
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition APFloat.h:1397
An arbitrary precision integer that knows its signedness.
Definition APSInt.h:24
Container class for subtarget features.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
constexpr unsigned id() const
Definition MCRegister.h:82
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool isValidCBCond(AArch64CC::CondCode Code)
True, if a given condition code can be used in a fused compare-and-branch instructions,...
static CondCode getSwappedCondition(CondCode CC)
getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...
static const char * getCondCodeName(CondCode Code)
static CondCode getInvertedCondCode(CondCode Code)
static unsigned getNZCVToSatisfyCondCode(CondCode Code)
Given a condition code, return NZCV flags that would satisfy that condition.
TOF
Target Operand Flag enum.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
@ MO_NC
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow.
@ MO_G1
MO_G1 - A symbol operand with this flag (granule 1) represents the bits 16-31 of a 64-bit address,...
@ MO_S
MO_S - Indicates that the bits of the symbol operand represented by MO_G0 etc are signed.
@ MO_PAGEOFF
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
@ MO_PREL
MO_PREL - Indicates that the bits of the symbol operand represented by MO_G0 etc are PC relative.
@ MO_G0
MO_G0 - A symbol operand with this flag (granule 0) represents the bits 0-15 of a 64-bit address,...
@ MO_ARM64EC_CALLMANGLE
MO_ARM64EC_CALLMANGLE - Operand refers to the Arm64EC-mangled version of a symbol,...
@ MO_PAGE
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
@ MO_HI12
MO_HI12 - This flag indicates that a symbol operand represents the bits 13-24 of a 64-bit address,...
@ MO_TLS
MO_TLS - Indicates that the operand being accessed is some kind of thread-local symbol.
@ MO_G2
MO_G2 - A symbol operand with this flag (granule 2) represents the bits 32-47 of a 64-bit address,...
@ MO_TAGGED
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
@ MO_G3
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address,...
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
uint32_t parseGenericRegister(StringRef Name)
std::string genericRegisterString(uint32_t Bits)
static constexpr unsigned SVEMaxBitsPerVector
static constexpr unsigned SVEBitsPerBlock
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
TailFoldingOpts
An enum to describe what types of loops we should attempt to tail-fold: Disabled: None Reductions: Lo...
static unsigned getBTIHintNum(bool CallTarget, bool JumpTarget)
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
static AArch64Layout::VectorLayout AArch64StringToVectorLayout(StringRef LayoutStr)
static const char * AArch64VectorLayoutToString(AArch64Layout::VectorLayout Layout)
std::optional< unsigned > getSVEPredPatternFromNumElements(unsigned MinNumElts)
Return specific VL predicate pattern based on the number of elements.
static bool atomicBarrierDroppedOnZero(unsigned Opcode)
static MCRegister getXRegFromWReg(MCRegister Reg)
static MCRegister getXRegFromXRegTuple(MCRegister RegTuple)
static MCRegister getWRegFromXReg(MCRegister Reg)
unsigned getNumElementsFromSVEPredPattern(unsigned Pattern)
Return the number of active elements for VL1 to VL256 predicate pattern, zero for all other patterns.
static MCRegister getDRegFromBReg(MCRegister Reg)
@ Disabled
Don't do any conversion of .debug_str_offsets tables.
Definition DWP.h:30
static MCRegister getBRegFromDReg(MCRegister Reg)
static StringRef AArch64PACKeyIDToString(AArch64PACKey::ID KeyID)
Return 2-letter identifier string for numeric key ID.
#define N
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAliasImm(StringTable::Offset N, uint16_t E, uint16_t I)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAliasReg(StringTable::Offset N, uint16_t E, bool R)
constexpr SysAliasReg(StringTable::Offset N, uint16_t E, bool R)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAliasReg(StringTable::Offset N, uint16_t E, bool R)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAliasOptionalReg(StringTable::Offset N, uint16_t E, SysAliasRegUse R)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAlias(StringTable::Offset N, uint16_t E)
bool haveFeatures(FeatureBitset ActiveFeatures) const
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr TLBIPSysAlias(StringTable::Offset N, uint16_t E, SysAliasRegUse R, FeatureBitset F, bool AllowWithTLBID)
constexpr SysAliasOptionalReg(StringTable::Offset N, uint16_t E, SysAliasRegUse R)
constexpr SysAliasImm(StringTable::Offset N, uint16_t E, uint16_t I)
constexpr SysAliasImm(StringTable::Offset N, uint16_t E, uint16_t I, FeatureBitset F)
constexpr SysAliasOptionalReg(StringTable::Offset N, uint16_t E, SysAliasRegUse R)
constexpr SysAliasOptionalReg(StringTable::Offset N, uint16_t E, SysAliasRegUse R, FeatureBitset F)
constexpr SysAliasReg(StringTable::Offset N, uint16_t E, bool R)
constexpr SysAliasReg(StringTable::Offset N, uint16_t E, bool R, FeatureBitset F)
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
StringTable::Offset Name
FeatureBitset FeaturesRequired
constexpr SysAlias(StringTable::Offset N, uint16_t E)
constexpr SysAlias(StringTable::Offset N, uint16_t E, FeatureBitset F)
constexpr TLBIPSysAlias(StringTable::Offset N, uint16_t E, SysAliasRegUse R, FeatureBitset F, bool AllowWithTLBID)
bool haveFeatures(FeatureBitset ActiveFeatures) const