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"
29
30namespace llvm {
31
33 switch (Reg.id()) {
34 case AArch64::X0: return AArch64::W0;
35 case AArch64::X1: return AArch64::W1;
36 case AArch64::X2: return AArch64::W2;
37 case AArch64::X3: return AArch64::W3;
38 case AArch64::X4: return AArch64::W4;
39 case AArch64::X5: return AArch64::W5;
40 case AArch64::X6: return AArch64::W6;
41 case AArch64::X7: return AArch64::W7;
42 case AArch64::X8: return AArch64::W8;
43 case AArch64::X9: return AArch64::W9;
44 case AArch64::X10: return AArch64::W10;
45 case AArch64::X11: return AArch64::W11;
46 case AArch64::X12: return AArch64::W12;
47 case AArch64::X13: return AArch64::W13;
48 case AArch64::X14: return AArch64::W14;
49 case AArch64::X15: return AArch64::W15;
50 case AArch64::X16: return AArch64::W16;
51 case AArch64::X17: return AArch64::W17;
52 case AArch64::X18: return AArch64::W18;
53 case AArch64::X19: return AArch64::W19;
54 case AArch64::X20: return AArch64::W20;
55 case AArch64::X21: return AArch64::W21;
56 case AArch64::X22: return AArch64::W22;
57 case AArch64::X23: return AArch64::W23;
58 case AArch64::X24: return AArch64::W24;
59 case AArch64::X25: return AArch64::W25;
60 case AArch64::X26: return AArch64::W26;
61 case AArch64::X27: return AArch64::W27;
62 case AArch64::X28: return AArch64::W28;
63 case AArch64::FP: return AArch64::W29;
64 case AArch64::LR: return AArch64::W30;
65 case AArch64::SP: return AArch64::WSP;
66 case AArch64::XZR: return AArch64::WZR;
67 }
68 // For anything else, return it unchanged.
69 return Reg;
70}
71
73 switch (Reg.id()) {
74 case AArch64::W0: return AArch64::X0;
75 case AArch64::W1: return AArch64::X1;
76 case AArch64::W2: return AArch64::X2;
77 case AArch64::W3: return AArch64::X3;
78 case AArch64::W4: return AArch64::X4;
79 case AArch64::W5: return AArch64::X5;
80 case AArch64::W6: return AArch64::X6;
81 case AArch64::W7: return AArch64::X7;
82 case AArch64::W8: return AArch64::X8;
83 case AArch64::W9: return AArch64::X9;
84 case AArch64::W10: return AArch64::X10;
85 case AArch64::W11: return AArch64::X11;
86 case AArch64::W12: return AArch64::X12;
87 case AArch64::W13: return AArch64::X13;
88 case AArch64::W14: return AArch64::X14;
89 case AArch64::W15: return AArch64::X15;
90 case AArch64::W16: return AArch64::X16;
91 case AArch64::W17: return AArch64::X17;
92 case AArch64::W18: return AArch64::X18;
93 case AArch64::W19: return AArch64::X19;
94 case AArch64::W20: return AArch64::X20;
95 case AArch64::W21: return AArch64::X21;
96 case AArch64::W22: return AArch64::X22;
97 case AArch64::W23: return AArch64::X23;
98 case AArch64::W24: return AArch64::X24;
99 case AArch64::W25: return AArch64::X25;
100 case AArch64::W26: return AArch64::X26;
101 case AArch64::W27: return AArch64::X27;
102 case AArch64::W28: return AArch64::X28;
103 case AArch64::W29: return AArch64::FP;
104 case AArch64::W30: return AArch64::LR;
105 case AArch64::WSP: return AArch64::SP;
106 case AArch64::WZR: return AArch64::XZR;
107 }
108 // For anything else, return it unchanged.
109 return Reg;
110}
111
113 switch (RegTuple.id()) {
114 case AArch64::X0_X1_X2_X3_X4_X5_X6_X7: return AArch64::X0;
115 case AArch64::X2_X3_X4_X5_X6_X7_X8_X9: return AArch64::X2;
116 case AArch64::X4_X5_X6_X7_X8_X9_X10_X11: return AArch64::X4;
117 case AArch64::X6_X7_X8_X9_X10_X11_X12_X13: return AArch64::X6;
118 case AArch64::X8_X9_X10_X11_X12_X13_X14_X15: return AArch64::X8;
119 case AArch64::X10_X11_X12_X13_X14_X15_X16_X17: return AArch64::X10;
120 case AArch64::X12_X13_X14_X15_X16_X17_X18_X19: return AArch64::X12;
121 case AArch64::X14_X15_X16_X17_X18_X19_X20_X21: return AArch64::X14;
122 case AArch64::X16_X17_X18_X19_X20_X21_X22_X23: return AArch64::X16;
123 case AArch64::X18_X19_X20_X21_X22_X23_X24_X25: return AArch64::X18;
124 case AArch64::X20_X21_X22_X23_X24_X25_X26_X27: return AArch64::X20;
125 case AArch64::X22_X23_X24_X25_X26_X27_X28_FP: return AArch64::X22;
126 }
127 // For anything else, return it unchanged.
128 return RegTuple;
129}
130
132 switch (Reg.id()) {
133 case AArch64::D0: return AArch64::B0;
134 case AArch64::D1: return AArch64::B1;
135 case AArch64::D2: return AArch64::B2;
136 case AArch64::D3: return AArch64::B3;
137 case AArch64::D4: return AArch64::B4;
138 case AArch64::D5: return AArch64::B5;
139 case AArch64::D6: return AArch64::B6;
140 case AArch64::D7: return AArch64::B7;
141 case AArch64::D8: return AArch64::B8;
142 case AArch64::D9: return AArch64::B9;
143 case AArch64::D10: return AArch64::B10;
144 case AArch64::D11: return AArch64::B11;
145 case AArch64::D12: return AArch64::B12;
146 case AArch64::D13: return AArch64::B13;
147 case AArch64::D14: return AArch64::B14;
148 case AArch64::D15: return AArch64::B15;
149 case AArch64::D16: return AArch64::B16;
150 case AArch64::D17: return AArch64::B17;
151 case AArch64::D18: return AArch64::B18;
152 case AArch64::D19: return AArch64::B19;
153 case AArch64::D20: return AArch64::B20;
154 case AArch64::D21: return AArch64::B21;
155 case AArch64::D22: return AArch64::B22;
156 case AArch64::D23: return AArch64::B23;
157 case AArch64::D24: return AArch64::B24;
158 case AArch64::D25: return AArch64::B25;
159 case AArch64::D26: return AArch64::B26;
160 case AArch64::D27: return AArch64::B27;
161 case AArch64::D28: return AArch64::B28;
162 case AArch64::D29: return AArch64::B29;
163 case AArch64::D30: return AArch64::B30;
164 case AArch64::D31: return AArch64::B31;
165 }
166 // For anything else, return it unchanged.
167 return Reg;
168}
169
171 switch (Reg.id()) {
172 case AArch64::B0: return AArch64::D0;
173 case AArch64::B1: return AArch64::D1;
174 case AArch64::B2: return AArch64::D2;
175 case AArch64::B3: return AArch64::D3;
176 case AArch64::B4: return AArch64::D4;
177 case AArch64::B5: return AArch64::D5;
178 case AArch64::B6: return AArch64::D6;
179 case AArch64::B7: return AArch64::D7;
180 case AArch64::B8: return AArch64::D8;
181 case AArch64::B9: return AArch64::D9;
182 case AArch64::B10: return AArch64::D10;
183 case AArch64::B11: return AArch64::D11;
184 case AArch64::B12: return AArch64::D12;
185 case AArch64::B13: return AArch64::D13;
186 case AArch64::B14: return AArch64::D14;
187 case AArch64::B15: return AArch64::D15;
188 case AArch64::B16: return AArch64::D16;
189 case AArch64::B17: return AArch64::D17;
190 case AArch64::B18: return AArch64::D18;
191 case AArch64::B19: return AArch64::D19;
192 case AArch64::B20: return AArch64::D20;
193 case AArch64::B21: return AArch64::D21;
194 case AArch64::B22: return AArch64::D22;
195 case AArch64::B23: return AArch64::D23;
196 case AArch64::B24: return AArch64::D24;
197 case AArch64::B25: return AArch64::D25;
198 case AArch64::B26: return AArch64::D26;
199 case AArch64::B27: return AArch64::D27;
200 case AArch64::B28: return AArch64::D28;
201 case AArch64::B29: return AArch64::D29;
202 case AArch64::B30: return AArch64::D30;
203 case AArch64::B31: return AArch64::D31;
204 }
205 // For anything else, return it unchanged.
206 return Reg;
207}
208
209static inline bool atomicBarrierDroppedOnZero(unsigned Opcode) {
210 switch (Opcode) {
211 case AArch64::LDADDAB: case AArch64::LDADDAH:
212 case AArch64::LDADDAW: case AArch64::LDADDAX:
213 case AArch64::LDADDALB: case AArch64::LDADDALH:
214 case AArch64::LDADDALW: case AArch64::LDADDALX:
215 case AArch64::LDCLRAB: case AArch64::LDCLRAH:
216 case AArch64::LDCLRAW: case AArch64::LDCLRAX:
217 case AArch64::LDCLRALB: case AArch64::LDCLRALH:
218 case AArch64::LDCLRALW: case AArch64::LDCLRALX:
219 case AArch64::LDEORAB: case AArch64::LDEORAH:
220 case AArch64::LDEORAW: case AArch64::LDEORAX:
221 case AArch64::LDEORALB: case AArch64::LDEORALH:
222 case AArch64::LDEORALW: case AArch64::LDEORALX:
223 case AArch64::LDSETAB: case AArch64::LDSETAH:
224 case AArch64::LDSETAW: case AArch64::LDSETAX:
225 case AArch64::LDSETALB: case AArch64::LDSETALH:
226 case AArch64::LDSETALW: case AArch64::LDSETALX:
227 case AArch64::LDSMAXAB: case AArch64::LDSMAXAH:
228 case AArch64::LDSMAXAW: case AArch64::LDSMAXAX:
229 case AArch64::LDSMAXALB: case AArch64::LDSMAXALH:
230 case AArch64::LDSMAXALW: case AArch64::LDSMAXALX:
231 case AArch64::LDSMINAB: case AArch64::LDSMINAH:
232 case AArch64::LDSMINAW: case AArch64::LDSMINAX:
233 case AArch64::LDSMINALB: case AArch64::LDSMINALH:
234 case AArch64::LDSMINALW: case AArch64::LDSMINALX:
235 case AArch64::LDUMAXAB: case AArch64::LDUMAXAH:
236 case AArch64::LDUMAXAW: case AArch64::LDUMAXAX:
237 case AArch64::LDUMAXALB: case AArch64::LDUMAXALH:
238 case AArch64::LDUMAXALW: case AArch64::LDUMAXALX:
239 case AArch64::LDUMINAB: case AArch64::LDUMINAH:
240 case AArch64::LDUMINAW: case AArch64::LDUMINAX:
241 case AArch64::LDUMINALB: case AArch64::LDUMINALH:
242 case AArch64::LDUMINALW: case AArch64::LDUMINALX:
243 case AArch64::SWPAB: case AArch64::SWPAH:
244 case AArch64::SWPAW: case AArch64::SWPAX:
245 case AArch64::SWPALB: case AArch64::SWPALH:
246 case AArch64::SWPALW: case AArch64::SWPALX:
247 return true;
248 }
249 return false;
250}
251
252inline unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth,
253 bool isReciprocal) {
254 // An FCVT[SU] instruction performs: convertToInt(Val * 2^fbits) where fbits
255 // is between 1 and 32 for a destination w-register, or 1 and 64 for an
256 // x-register.
257 //
258 // By this stage, we've detected (fp_to_[su]int (fmul Val, THIS_NODE)) so we
259 // want THIS_NODE to be 2^fbits. This is much easier to deal with using
260 // integers.
261 bool IsExact;
262
263 if (isReciprocal)
264 if (!FVal.getExactInverse(&FVal))
265 return 0;
266
267 // fbits is between 1 and 64 in the worst-case, which means the fmul
268 // could have 2^64 as an actual operand. Need 65 bits of precision.
269 APSInt IntVal(65, true);
270 FVal.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact);
271
272 // N.b. isPowerOf2 also checks for > 0.
273 if (!IsExact || !IntVal.isPowerOf2())
274 return 0;
275 unsigned FBits = IntVal.logBase2();
276
277 // Checks above should have guaranteed that we haven't lost information in
278 // finding FBits, but it must still be in range.
279 if (FBits == 0 || FBits > RegWidth)
280 return 0;
281 return FBits;
282}
283
284namespace AArch64CC {
285
286// The CondCodes constants map directly to the 4-bit encoding of the condition
287// field for predicated instructions.
288enum CondCode { // Meaning (integer) Meaning (floating-point)
289 EQ = 0x0, // Equal Equal
290 NE = 0x1, // Not equal Not equal, or unordered
291 HS = 0x2, // Unsigned higher or same >, ==, or unordered
292 LO = 0x3, // Unsigned lower Less than
293 MI = 0x4, // Minus, negative Less than
294 PL = 0x5, // Plus, positive or zero >, ==, or unordered
295 VS = 0x6, // Overflow Unordered
296 VC = 0x7, // No overflow Not unordered
297 HI = 0x8, // Unsigned higher Greater than, or unordered
298 LS = 0x9, // Unsigned lower or same Less than or equal
299 GE = 0xa, // Greater than or equal Greater than or equal
300 LT = 0xb, // Less than Less than, or unordered
301 GT = 0xc, // Greater than Greater than
302 LE = 0xd, // Less than or equal <, ==, or unordered
303 AL = 0xe, // Always (unconditional) Always (unconditional)
304 NV = 0xf, // Always (unconditional) Always (unconditional)
305 // Note the NV exists purely to disassemble 0b1111. Execution is "always".
307
308 // Common aliases used for SVE.
309 ANY_ACTIVE = NE, // (!Z)
310 FIRST_ACTIVE = MI, // ( N)
311 LAST_ACTIVE = LO, // (!C)
312 NONE_ACTIVE = EQ // ( Z)
313};
314
315inline static const char *getCondCodeName(CondCode Code) {
316 switch (Code) {
317 default: llvm_unreachable("Unknown condition code");
318 case EQ: return "eq";
319 case NE: return "ne";
320 case HS: return "hs";
321 case LO: return "lo";
322 case MI: return "mi";
323 case PL: return "pl";
324 case VS: return "vs";
325 case VC: return "vc";
326 case HI: return "hi";
327 case LS: return "ls";
328 case GE: return "ge";
329 case LT: return "lt";
330 case GT: return "gt";
331 case LE: return "le";
332 case AL: return "al";
333 case NV: return "nv";
334 }
335}
336
338 // To reverse a condition it's necessary to only invert the low bit:
339
340 return static_cast<CondCode>(static_cast<unsigned>(Code) ^ 0x1);
341}
342
343/// getSwappedCondition - assume the flags are set by MI(a,b), return
344/// the condition code if we modify the instructions such that flags are
345/// set by MI(b,a).
347 switch (CC) {
348 default:
349 return AL;
350 case EQ:
351 return EQ;
352 case NE:
353 return NE;
354 case HS:
355 return LS;
356 case LO:
357 return HI;
358 case HI:
359 return LO;
360 case LS:
361 return HS;
362 case GE:
363 return LE;
364 case LT:
365 return GT;
366 case GT:
367 return LT;
368 case LE:
369 return GE;
370 }
371}
372
373/// Given a condition code, return NZCV flags that would satisfy that condition.
374/// The flag bits are in the format expected by the ccmp instructions.
375/// Note that many different flag settings can satisfy a given condition code,
376/// this function just returns one of them.
377inline static unsigned getNZCVToSatisfyCondCode(CondCode Code) {
378 // NZCV flags encoded as expected by ccmp instructions, ARMv8 ISA 5.5.7.
379 enum { N = 8, Z = 4, C = 2, V = 1 };
380 switch (Code) {
381 default: llvm_unreachable("Unknown condition code");
382 case EQ: return Z; // Z == 1
383 case NE: return 0; // Z == 0
384 case HS: return C; // C == 1
385 case LO: return 0; // C == 0
386 case MI: return N; // N == 1
387 case PL: return 0; // N == 0
388 case VS: return V; // V == 1
389 case VC: return 0; // V == 0
390 case HI: return C; // C == 1 && Z == 0
391 case LS: return 0; // C == 0 || Z == 1
392 case GE: return 0; // N == V
393 case LT: return N; // N != V
394 case GT: return 0; // Z == 0 && N == V
395 case LE: return Z; // Z == 1 || N != V
396 }
397}
398
399/// True, if a given condition code can be used in a fused compare-and-branch
400/// instructions, false otherwise.
401inline static bool isValidCBCond(AArch64CC::CondCode Code) {
402 switch (Code) {
403 default:
404 return false;
405 case AArch64CC::EQ:
406 case AArch64CC::NE:
407 case AArch64CC::HS:
408 case AArch64CC::LO:
409 case AArch64CC::HI:
410 case AArch64CC::LS:
411 case AArch64CC::GE:
412 case AArch64CC::LT:
413 case AArch64CC::GT:
414 case AArch64CC::LE:
415 return true;
416 }
417}
418
419} // end namespace AArch64CC
420
421struct SysAlias {
422 const char *Name;
425
426 constexpr SysAlias(const char *N, uint16_t E) : Name(N), Encoding(E) {}
427 constexpr SysAlias(const char *N, uint16_t E, FeatureBitset F)
429
430 bool haveFeatures(FeatureBitset ActiveFeatures) const {
431 return ActiveFeatures[llvm::AArch64::FeatureAll] ||
432 (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
433 }
434
436};
437
438#define GET_SysAliasRegUse_DECL
439#include "AArch64GenSystemOperands.inc"
440
443 constexpr SysAliasReg(const char *N, uint16_t E, bool R)
444 : SysAlias(N, E), NeedsReg(R) {}
445 constexpr SysAliasReg(const char *N, uint16_t E, bool R, FeatureBitset F)
446 : SysAlias(N, E, F), NeedsReg(R) {}
447};
448
450 SysAliasRegUse RegUse;
451 constexpr SysAliasOptionalReg(const char *N, uint16_t E, SysAliasRegUse R)
452 : SysAlias(N, E), RegUse(R) {}
453 constexpr SysAliasOptionalReg(const char *N, uint16_t E, SysAliasRegUse R,
455 : SysAlias(N, E, F), RegUse(R) {}
456};
457
460
461 constexpr TLBIPSysAlias(const char *N, uint16_t E, SysAliasRegUse R,
464
465 bool haveFeatures(FeatureBitset ActiveFeatures) const {
466 return SysAliasOptionalReg::haveFeatures(ActiveFeatures) &&
467 (ActiveFeatures[llvm::AArch64::FeatureAll] ||
468 ActiveFeatures[llvm::AArch64::FeatureD128] ||
469 (AllowWithTLBID && ActiveFeatures[llvm::AArch64::FeatureTLBID]));
470 }
471};
472
475 constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I)
476 : SysAlias(N, E), ImmValue(I) {}
477 constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I, FeatureBitset F)
478 : SysAlias(N, E, F), ImmValue(I) {}
479};
480
481namespace AArch64SVCR {
482 struct SVCR : SysAlias{
483 using SysAlias::SysAlias;
484 };
485#define GET_SVCRValues_DECL
486#define GET_SVCRsList_DECL
487#include "AArch64GenSystemOperands.inc"
488}
489
490namespace AArch64AT{
491 struct AT : SysAlias {
492 using SysAlias::SysAlias;
493 };
494#define GET_ATValues_DECL
495#define GET_ATsList_DECL
496#include "AArch64GenSystemOperands.inc"
497}
498
499namespace AArch64DB {
500 struct DB : SysAlias {
501 using SysAlias::SysAlias;
502 };
503#define GET_DBValues_DECL
504#define GET_DBsList_DECL
505#include "AArch64GenSystemOperands.inc"
506}
507
508namespace AArch64DBnXS {
511 };
512#define GET_DBnXSValues_DECL
513#define GET_DBnXSsList_DECL
514#include "AArch64GenSystemOperands.inc"
515}
516
517namespace AArch64DC {
518 struct DC : SysAlias {
519 using SysAlias::SysAlias;
520 };
521#define GET_DCValues_DECL
522#define GET_DCsList_DECL
523#include "AArch64GenSystemOperands.inc"
524}
525
526namespace AArch64IC {
527 struct IC : SysAliasReg {
529 };
530#define GET_ICValues_DECL
531#define GET_ICsList_DECL
532#include "AArch64GenSystemOperands.inc"
533}
534
535namespace AArch64ISB {
536 struct ISB : SysAlias {
537 using SysAlias::SysAlias;
538 };
539#define GET_ISBValues_DECL
540#define GET_ISBsList_DECL
541#include "AArch64GenSystemOperands.inc"
542}
543
544namespace AArch64TSB {
545 struct TSB : SysAlias {
546 using SysAlias::SysAlias;
547 };
548#define GET_TSBValues_DECL
549#define GET_TSBsList_DECL
550#include "AArch64GenSystemOperands.inc"
551}
552
553namespace AArch64PRFM {
554 struct PRFM : SysAlias {
555 using SysAlias::SysAlias;
556 };
557#define GET_PRFMValues_DECL
558#define GET_PRFMsList_DECL
559#include "AArch64GenSystemOperands.inc"
560}
561
562namespace AArch64SVEPRFM {
563 struct SVEPRFM : SysAlias {
564 using SysAlias::SysAlias;
565 };
566#define GET_SVEPRFMValues_DECL
567#define GET_SVEPRFMsList_DECL
568#include "AArch64GenSystemOperands.inc"
569}
570
571namespace AArch64RPRFM {
572struct RPRFM : SysAlias {
573 using SysAlias::SysAlias;
574};
575#define GET_RPRFMValues_DECL
576#define GET_RPRFMsList_DECL
577#include "AArch64GenSystemOperands.inc"
578} // namespace AArch64RPRFM
579
580namespace AArch64SVEPredPattern {
581 struct SVEPREDPAT {
582 const char *Name;
584 };
585#define GET_SVEPREDPATValues_DECL
586#define GET_SVEPREDPATsList_DECL
587#include "AArch64GenSystemOperands.inc"
588}
589
592 const char *Name;
594 };
595#define GET_SVEVECLENSPECIFIERValues_DECL
596#define GET_SVEVECLENSPECIFIERsList_DECL
597#include "AArch64GenSystemOperands.inc"
598} // namespace AArch64SVEVecLenSpecifier
599
600/// Return the number of active elements for VL1 to VL256 predicate pattern,
601/// zero for all other patterns.
602inline unsigned getNumElementsFromSVEPredPattern(unsigned Pattern) {
603 switch (Pattern) {
604 default:
605 return 0;
606 case AArch64SVEPredPattern::vl1:
607 case AArch64SVEPredPattern::vl2:
608 case AArch64SVEPredPattern::vl3:
609 case AArch64SVEPredPattern::vl4:
610 case AArch64SVEPredPattern::vl5:
611 case AArch64SVEPredPattern::vl6:
612 case AArch64SVEPredPattern::vl7:
613 case AArch64SVEPredPattern::vl8:
614 return Pattern;
615 case AArch64SVEPredPattern::vl16:
616 return 16;
617 case AArch64SVEPredPattern::vl32:
618 return 32;
619 case AArch64SVEPredPattern::vl64:
620 return 64;
621 case AArch64SVEPredPattern::vl128:
622 return 128;
623 case AArch64SVEPredPattern::vl256:
624 return 256;
625 }
626}
627
628/// Return specific VL predicate pattern based on the number of elements.
629inline std::optional<unsigned>
631 switch (MinNumElts) {
632 default:
633 return std::nullopt;
634 case 1:
635 case 2:
636 case 3:
637 case 4:
638 case 5:
639 case 6:
640 case 7:
641 case 8:
642 return MinNumElts;
643 case 16:
644 return AArch64SVEPredPattern::vl16;
645 case 32:
646 return AArch64SVEPredPattern::vl32;
647 case 64:
648 return AArch64SVEPredPattern::vl64;
649 case 128:
650 return AArch64SVEPredPattern::vl128;
651 case 256:
652 return AArch64SVEPredPattern::vl256;
653 }
654}
655
656/// An enum to describe what types of loops we should attempt to tail-fold:
657/// Disabled: None
658/// Reductions: Loops containing reductions
659/// Recurrences: Loops with first-order recurrences, i.e. that would
660/// require a SVE splice instruction
661/// Reverse: Reverse loops
662/// Simple: Loops that are not reversed and don't contain reductions
663/// or first-order recurrences.
664/// All: All
673
675 /* LargestValue */ (long)TailFoldingOpts::Reverse);
676
677namespace AArch64ExactFPImm {
679 int Enum;
680 const char *Repr;
681};
682#define GET_ExactFPImmValues_DECL
683#define GET_ExactFPImmsList_DECL
684#include "AArch64GenSystemOperands.inc"
685}
686
687namespace AArch64PState {
689 using SysAlias::SysAlias;
690 };
691#define GET_PStateImm0_15Values_DECL
692#define GET_PStateImm0_15sList_DECL
693#include "AArch64GenSystemOperands.inc"
694
696 using SysAlias::SysAlias;
697 };
698#define GET_PStateImm0_1Values_DECL
699#define GET_PStateImm0_1sList_DECL
700#include "AArch64GenSystemOperands.inc"
701}
702
703namespace AArch64PSBHint {
704 struct PSB : SysAlias {
705 using SysAlias::SysAlias;
706 };
707#define GET_PSBValues_DECL
708#define GET_PSBsList_DECL
709#include "AArch64GenSystemOperands.inc"
710}
711
712namespace AArch64PHint {
713struct PHint {
714 const char *Name;
715 unsigned Encoding;
717
718 bool haveFeatures(FeatureBitset ActiveFeatures) const {
719 return ActiveFeatures[llvm::AArch64::FeatureAll] ||
720 (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
721 }
722};
723
724#define GET_PHintValues_DECL
725#define GET_PHintsList_DECL
726#include "AArch64GenSystemOperands.inc"
727
730} // namespace AArch64PHint
731
732namespace AArch64BTIHint {
733 struct BTI : SysAlias {
734 using SysAlias::SysAlias;
735 };
736#define GET_BTIValues_DECL
737#define GET_BTIsList_DECL
738#include "AArch64GenSystemOperands.inc"
739}
740
741namespace AArch64CMHPriorityHint {
743 using SysAlias::SysAlias;
744};
745#define GET_CMHPRIORITYHINT_DECL
746#include "AArch64GenSystemOperands.inc"
747} // namespace AArch64CMHPriorityHint
748
749namespace AArch64TIndexHint {
750struct TIndex : SysAlias {
751 using SysAlias::SysAlias;
752};
753#define GET_TINDEX_DECL
754#include "AArch64GenSystemOperands.inc"
755} // namespace AArch64TIndexHint
756
764
785
786namespace AArch64Layout {
793
798
799 // Bare layout for the 128-bit vector
800 // (only show ".b", ".h", ".s", ".d" without vector number)
805 };
806}
807
808inline static const char *
810 switch (Layout) {
811 case AArch64Layout::VL_8B: return ".8b";
812 case AArch64Layout::VL_4H: return ".4h";
813 case AArch64Layout::VL_2S: return ".2s";
814 case AArch64Layout::VL_1D: return ".1d";
815 case AArch64Layout::VL_16B: return ".16b";
816 case AArch64Layout::VL_8H: return ".8h";
817 case AArch64Layout::VL_4S: return ".4s";
818 case AArch64Layout::VL_2D: return ".2d";
819 case AArch64Layout::VL_B: return ".b";
820 case AArch64Layout::VL_H: return ".h";
821 case AArch64Layout::VL_S: return ".s";
822 case AArch64Layout::VL_D: return ".d";
823 default: llvm_unreachable("Unknown Vector Layout");
824 }
825}
826
827inline static AArch64Layout::VectorLayout
844
845namespace AArch64SysReg {
846 struct SysReg {
847 const char Name[32];
848 unsigned Encoding;
852
853 bool haveFeatures(FeatureBitset ActiveFeatures) const {
854 return ActiveFeatures[llvm::AArch64::FeatureAll] ||
855 (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
856 }
857 };
858
859#define GET_SysRegsList_DECL
860#define GET_SysRegValues_DECL
861#include "AArch64GenSystemOperands.inc"
862
863 uint32_t parseGenericRegister(StringRef Name);
864 std::string genericRegisterString(uint32_t Bits);
865}
866
867namespace AArch64TLBI {
871#define GET_TLBITable_DECL
872#include "AArch64GenSystemOperands.inc"
873}
874
875namespace AArch64TLBIP {
879#define GET_TLBIPTable_DECL
880#include "AArch64GenSystemOperands.inc"
881} // namespace AArch64TLBIP
882
883namespace AArch64MLBI {
886};
887#define GET_MLBITable_DECL
888#include "AArch64GenSystemOperands.inc"
889} // namespace AArch64MLBI
890
891namespace AArch64GIC {
892struct GIC : SysAliasReg {
894};
895#define GET_GICTable_DECL
896#include "AArch64GenSystemOperands.inc"
897} // namespace AArch64GIC
898
899namespace AArch64GICR {
902};
903#define GET_GICRTable_DECL
904#include "AArch64GenSystemOperands.inc"
905} // namespace AArch64GICR
906
907namespace AArch64GSB {
908struct GSB : SysAlias {
909 using SysAlias::SysAlias;
910};
911#define GET_GSBTable_DECL
912#include "AArch64GenSystemOperands.inc"
913} // namespace AArch64GSB
914
915namespace AArch64PLBI {
919#define GET_PLBITable_DECL
920#include "AArch64GenSystemOperands.inc"
921} // namespace AArch64PLBI
922
923namespace AArch64II {
924/// Target Operand Flag enum.
925enum TOF {
926 //===------------------------------------------------------------------===//
927 // AArch64 Specific MachineOperand flags.
928
930
932
933 /// MO_PAGE - A symbol operand with this flag represents the pc-relative
934 /// offset of the 4K page containing the symbol. This is used with the
935 /// ADRP instruction.
937
938 /// MO_PAGEOFF - A symbol operand with this flag represents the offset of
939 /// that symbol within a 4K page. This offset is added to the page address
940 /// to produce the complete address.
942
943 /// MO_G3 - A symbol operand with this flag (granule 3) represents the high
944 /// 16-bits of a 64-bit address, used in a MOVZ or MOVK instruction
945 MO_G3 = 3,
946
947 /// MO_G2 - A symbol operand with this flag (granule 2) represents the bits
948 /// 32-47 of a 64-bit address, used in a MOVZ or MOVK instruction
949 MO_G2 = 4,
950
951 /// MO_G1 - A symbol operand with this flag (granule 1) represents the bits
952 /// 16-31 of a 64-bit address, used in a MOVZ or MOVK instruction
953 MO_G1 = 5,
954
955 /// MO_G0 - A symbol operand with this flag (granule 0) represents the bits
956 /// 0-15 of a 64-bit address, used in a MOVZ or MOVK instruction
957 MO_G0 = 6,
958
959 /// MO_HI12 - This flag indicates that a symbol operand represents the bits
960 /// 13-24 of a 64-bit address, used in a arithmetic immediate-shifted-left-
961 /// by-12-bits instruction.
963
964 /// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
965 /// reference is actually to the ".refptr.FOO" symbol. This is used for
966 /// stub symbols on windows.
968
969 /// MO_GOT - This flag indicates that a symbol operand represents the
970 /// address of the GOT entry for the symbol, rather than the address of
971 /// the symbol itself.
972 MO_GOT = 0x10,
973
974 /// MO_NC - Indicates whether the linker is expected to check the symbol
975 /// reference for overflow. For example in an ADRP/ADD pair of relocations
976 /// the ADRP usually does check, but not the ADD.
977 MO_NC = 0x20,
978
979 /// MO_TLS - Indicates that the operand being accessed is some kind of
980 /// thread-local symbol. On Darwin, only one type of thread-local access
981 /// exists (pre linker-relaxation), but on ELF the TLSModel used for the
982 /// referee will affect interpretation.
983 MO_TLS = 0x40,
984
985 /// MO_DLLIMPORT - On a symbol operand, this represents that the reference
986 /// to the symbol is for an import stub. This is used for DLL import
987 /// storage class indication on Windows.
989
990 /// MO_S - Indicates that the bits of the symbol operand represented by
991 /// MO_G0 etc are signed.
992 MO_S = 0x100,
993
994 /// MO_PREL - Indicates that the bits of the symbol operand represented by
995 /// MO_G0 etc are PC relative.
996 MO_PREL = 0x200,
997
998 /// MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag
999 /// in bits 56-63.
1000 /// On a FrameIndex operand, indicates that the underlying memory is tagged
1001 /// with an unknown tag value (MTE); this needs to be lowered either to an
1002 /// SP-relative load or store instruction (which do not check tags), or to
1003 /// an LDG instruction to obtain the tag value.
1004 MO_TAGGED = 0x400,
1005
1006 /// MO_ARM64EC_CALLMANGLE - Operand refers to the Arm64EC-mangled version
1007 /// of a symbol, not the original. For dllimport symbols, this means it
1008 /// uses "__imp_aux". For other symbols, this means it uses the mangled
1009 /// ("#" prefix for C) name.
1011};
1012} // end namespace AArch64II
1013
1014//===----------------------------------------------------------------------===//
1015// v8.3a Pointer Authentication
1016//
1017
1018namespace AArch64PACKey {
1019enum ID : uint8_t {
1020 IA = 0,
1021 IB = 1,
1022 DA = 2,
1023 DB = 3,
1025};
1026} // namespace AArch64PACKey
1027
1028/// Return 2-letter identifier string for numeric key ID.
1030 switch (KeyID) {
1031 case AArch64PACKey::IA:
1032 return StringRef("ia");
1033 case AArch64PACKey::IB:
1034 return StringRef("ib");
1035 case AArch64PACKey::DA:
1036 return StringRef("da");
1037 case AArch64PACKey::DB:
1038 return StringRef("db");
1039 }
1040 llvm_unreachable("Unhandled AArch64PACKey::ID enum");
1041}
1042
1043/// Return numeric key ID for 2-letter identifier string.
1044inline static std::optional<AArch64PACKey::ID>
1046 if (Name == "ia")
1047 return AArch64PACKey::IA;
1048 if (Name == "ib")
1049 return AArch64PACKey::IB;
1050 if (Name == "da")
1051 return AArch64PACKey::DA;
1052 if (Name == "db")
1053 return AArch64PACKey::DB;
1054 return std::nullopt;
1055}
1056
1057inline static unsigned getBTIHintNum(bool CallTarget, bool JumpTarget) {
1058 unsigned HintNum = 32;
1059 if (CallTarget)
1060 HintNum |= 2;
1061 if (JumpTarget)
1062 HintNum |= 4;
1063 assert(HintNum != 32 && "No target kinds!");
1064 return HintNum;
1065}
1066
1067namespace AArch64 {
1068// The number of bits in a SVE register is architecturally defined
1069// to be a multiple of this value. If <M x t> has this number of bits,
1070// a <n x M x t> vector can be stored in a SVE register without any
1071// redundant bits. If <M x t> has this number of bits divided by P,
1072// a <n x M x t> vector is stored in a SVE register by placing index i
1073// in index i*P of a <n x (M*P) x t> vector. The other elements of the
1074// <n x (M*P) x t> vector (such as index 1) are undefined.
1075static constexpr unsigned SVEBitsPerBlock = 128;
1076static constexpr unsigned SVEMaxBitsPerVector = 2048;
1077} // end namespace AArch64
1078} // end namespace llvm
1079
1080#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:348
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:5832
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition APFloat.h:1387
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
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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 "....
const PHint * lookupPHintByName(StringRef)
const PHint * lookupPHintByEncoding(uint16_t)
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:26
static MCRegister getBRegFromDReg(MCRegister Reg)
static StringRef AArch64PACKeyIDToString(AArch64PACKey::ID KeyID)
Return 2-letter identifier string for numeric key ID.
#define N
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAliasReg(const char *N, uint16_t E, bool R)
constexpr SysAliasReg(const char *N, uint16_t E, bool R)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAliasReg(const char *N, uint16_t E, bool R)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAliasReg(const char *N, uint16_t E, bool R)
bool haveFeatures(FeatureBitset ActiveFeatures) const
constexpr SysAliasOptionalReg(const char *N, uint16_t E, SysAliasRegUse R)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAlias(const char *N, uint16_t E)
bool haveFeatures(FeatureBitset ActiveFeatures) const
constexpr SysAlias(const char *N, uint16_t E)
constexpr TLBIPSysAlias(const char *N, uint16_t E, SysAliasRegUse R, FeatureBitset F, bool AllowWithTLBID)
constexpr SysAliasOptionalReg(const char *N, uint16_t E, SysAliasRegUse R)
constexpr SysAlias(const char *N, uint16_t E)
constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I)
constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I, FeatureBitset F)
constexpr SysAliasOptionalReg(const char *N, uint16_t E, SysAliasRegUse R, FeatureBitset F)
constexpr SysAliasOptionalReg(const char *N, uint16_t E, SysAliasRegUse R)
constexpr SysAliasReg(const char *N, uint16_t E, bool R, FeatureBitset F)
constexpr SysAliasReg(const char *N, uint16_t E, bool R)
bool haveFeatures(FeatureBitset ActiveFeatures) const
constexpr SysAlias(const char *N, uint16_t E)
FeatureBitset getRequiredFeatures() const
const char * Name
FeatureBitset FeaturesRequired
constexpr SysAlias(const char *N, uint16_t E, FeatureBitset F)
bool haveFeatures(FeatureBitset ActiveFeatures) const
constexpr TLBIPSysAlias(const char *N, uint16_t E, SysAliasRegUse R, FeatureBitset F, bool AllowWithTLBID)