brintos

brintos / llvm-project-archived public Read only

0
0
Text · 31.3 KiB · 0c98fdc Raw
1030 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains small standalone helper functions and enum definitions for10// the AArch64 target useful for the compiler back-end and the MC libraries.11// As such, it deliberately does not include references to LLVM core12// code gen types, passes, etc..13//14//===----------------------------------------------------------------------===//15 16#ifndef LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64BASEINFO_H17#define LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64BASEINFO_H18 19// FIXME: Is it easiest to fix this layering violation by moving the .inc20// #includes from AArch64MCTargetDesc.h to here?21#include "MCTargetDesc/AArch64MCTargetDesc.h" // For AArch64::X0 and friends.22#include "llvm/ADT/BitmaskEnum.h"23#include "llvm/ADT/STLExtras.h"24#include "llvm/ADT/StringSwitch.h"25#include "llvm/Support/ErrorHandling.h"26#include "llvm/TargetParser/SubtargetFeature.h"27 28namespace llvm {29 30inline static MCRegister getWRegFromXReg(MCRegister Reg) {31  switch (Reg.id()) {32  case AArch64::X0: return AArch64::W0;33  case AArch64::X1: return AArch64::W1;34  case AArch64::X2: return AArch64::W2;35  case AArch64::X3: return AArch64::W3;36  case AArch64::X4: return AArch64::W4;37  case AArch64::X5: return AArch64::W5;38  case AArch64::X6: return AArch64::W6;39  case AArch64::X7: return AArch64::W7;40  case AArch64::X8: return AArch64::W8;41  case AArch64::X9: return AArch64::W9;42  case AArch64::X10: return AArch64::W10;43  case AArch64::X11: return AArch64::W11;44  case AArch64::X12: return AArch64::W12;45  case AArch64::X13: return AArch64::W13;46  case AArch64::X14: return AArch64::W14;47  case AArch64::X15: return AArch64::W15;48  case AArch64::X16: return AArch64::W16;49  case AArch64::X17: return AArch64::W17;50  case AArch64::X18: return AArch64::W18;51  case AArch64::X19: return AArch64::W19;52  case AArch64::X20: return AArch64::W20;53  case AArch64::X21: return AArch64::W21;54  case AArch64::X22: return AArch64::W22;55  case AArch64::X23: return AArch64::W23;56  case AArch64::X24: return AArch64::W24;57  case AArch64::X25: return AArch64::W25;58  case AArch64::X26: return AArch64::W26;59  case AArch64::X27: return AArch64::W27;60  case AArch64::X28: return AArch64::W28;61  case AArch64::FP: return AArch64::W29;62  case AArch64::LR: return AArch64::W30;63  case AArch64::SP: return AArch64::WSP;64  case AArch64::XZR: return AArch64::WZR;65  }66  // For anything else, return it unchanged.67  return Reg;68}69 70inline static MCRegister getXRegFromWReg(MCRegister Reg) {71  switch (Reg.id()) {72  case AArch64::W0: return AArch64::X0;73  case AArch64::W1: return AArch64::X1;74  case AArch64::W2: return AArch64::X2;75  case AArch64::W3: return AArch64::X3;76  case AArch64::W4: return AArch64::X4;77  case AArch64::W5: return AArch64::X5;78  case AArch64::W6: return AArch64::X6;79  case AArch64::W7: return AArch64::X7;80  case AArch64::W8: return AArch64::X8;81  case AArch64::W9: return AArch64::X9;82  case AArch64::W10: return AArch64::X10;83  case AArch64::W11: return AArch64::X11;84  case AArch64::W12: return AArch64::X12;85  case AArch64::W13: return AArch64::X13;86  case AArch64::W14: return AArch64::X14;87  case AArch64::W15: return AArch64::X15;88  case AArch64::W16: return AArch64::X16;89  case AArch64::W17: return AArch64::X17;90  case AArch64::W18: return AArch64::X18;91  case AArch64::W19: return AArch64::X19;92  case AArch64::W20: return AArch64::X20;93  case AArch64::W21: return AArch64::X21;94  case AArch64::W22: return AArch64::X22;95  case AArch64::W23: return AArch64::X23;96  case AArch64::W24: return AArch64::X24;97  case AArch64::W25: return AArch64::X25;98  case AArch64::W26: return AArch64::X26;99  case AArch64::W27: return AArch64::X27;100  case AArch64::W28: return AArch64::X28;101  case AArch64::W29: return AArch64::FP;102  case AArch64::W30: return AArch64::LR;103  case AArch64::WSP: return AArch64::SP;104  case AArch64::WZR: return AArch64::XZR;105  }106  // For anything else, return it unchanged.107  return Reg;108}109 110inline static MCRegister getXRegFromXRegTuple(MCRegister RegTuple) {111  switch (RegTuple.id()) {112  case AArch64::X0_X1_X2_X3_X4_X5_X6_X7: return AArch64::X0;113  case AArch64::X2_X3_X4_X5_X6_X7_X8_X9: return AArch64::X2;114  case AArch64::X4_X5_X6_X7_X8_X9_X10_X11: return AArch64::X4;115  case AArch64::X6_X7_X8_X9_X10_X11_X12_X13: return AArch64::X6;116  case AArch64::X8_X9_X10_X11_X12_X13_X14_X15: return AArch64::X8;117  case AArch64::X10_X11_X12_X13_X14_X15_X16_X17: return AArch64::X10;118  case AArch64::X12_X13_X14_X15_X16_X17_X18_X19: return AArch64::X12;119  case AArch64::X14_X15_X16_X17_X18_X19_X20_X21: return AArch64::X14;120  case AArch64::X16_X17_X18_X19_X20_X21_X22_X23: return AArch64::X16;121  case AArch64::X18_X19_X20_X21_X22_X23_X24_X25: return AArch64::X18;122  case AArch64::X20_X21_X22_X23_X24_X25_X26_X27: return AArch64::X20;123  case AArch64::X22_X23_X24_X25_X26_X27_X28_FP: return AArch64::X22;124  }125  // For anything else, return it unchanged.126  return RegTuple;127}128 129static inline MCRegister getBRegFromDReg(MCRegister Reg) {130  switch (Reg.id()) {131  case AArch64::D0:  return AArch64::B0;132  case AArch64::D1:  return AArch64::B1;133  case AArch64::D2:  return AArch64::B2;134  case AArch64::D3:  return AArch64::B3;135  case AArch64::D4:  return AArch64::B4;136  case AArch64::D5:  return AArch64::B5;137  case AArch64::D6:  return AArch64::B6;138  case AArch64::D7:  return AArch64::B7;139  case AArch64::D8:  return AArch64::B8;140  case AArch64::D9:  return AArch64::B9;141  case AArch64::D10: return AArch64::B10;142  case AArch64::D11: return AArch64::B11;143  case AArch64::D12: return AArch64::B12;144  case AArch64::D13: return AArch64::B13;145  case AArch64::D14: return AArch64::B14;146  case AArch64::D15: return AArch64::B15;147  case AArch64::D16: return AArch64::B16;148  case AArch64::D17: return AArch64::B17;149  case AArch64::D18: return AArch64::B18;150  case AArch64::D19: return AArch64::B19;151  case AArch64::D20: return AArch64::B20;152  case AArch64::D21: return AArch64::B21;153  case AArch64::D22: return AArch64::B22;154  case AArch64::D23: return AArch64::B23;155  case AArch64::D24: return AArch64::B24;156  case AArch64::D25: return AArch64::B25;157  case AArch64::D26: return AArch64::B26;158  case AArch64::D27: return AArch64::B27;159  case AArch64::D28: return AArch64::B28;160  case AArch64::D29: return AArch64::B29;161  case AArch64::D30: return AArch64::B30;162  case AArch64::D31: return AArch64::B31;163  }164  // For anything else, return it unchanged.165  return Reg;166}167 168static inline MCRegister getDRegFromBReg(MCRegister Reg) {169  switch (Reg.id()) {170  case AArch64::B0:  return AArch64::D0;171  case AArch64::B1:  return AArch64::D1;172  case AArch64::B2:  return AArch64::D2;173  case AArch64::B3:  return AArch64::D3;174  case AArch64::B4:  return AArch64::D4;175  case AArch64::B5:  return AArch64::D5;176  case AArch64::B6:  return AArch64::D6;177  case AArch64::B7:  return AArch64::D7;178  case AArch64::B8:  return AArch64::D8;179  case AArch64::B9:  return AArch64::D9;180  case AArch64::B10: return AArch64::D10;181  case AArch64::B11: return AArch64::D11;182  case AArch64::B12: return AArch64::D12;183  case AArch64::B13: return AArch64::D13;184  case AArch64::B14: return AArch64::D14;185  case AArch64::B15: return AArch64::D15;186  case AArch64::B16: return AArch64::D16;187  case AArch64::B17: return AArch64::D17;188  case AArch64::B18: return AArch64::D18;189  case AArch64::B19: return AArch64::D19;190  case AArch64::B20: return AArch64::D20;191  case AArch64::B21: return AArch64::D21;192  case AArch64::B22: return AArch64::D22;193  case AArch64::B23: return AArch64::D23;194  case AArch64::B24: return AArch64::D24;195  case AArch64::B25: return AArch64::D25;196  case AArch64::B26: return AArch64::D26;197  case AArch64::B27: return AArch64::D27;198  case AArch64::B28: return AArch64::D28;199  case AArch64::B29: return AArch64::D29;200  case AArch64::B30: return AArch64::D30;201  case AArch64::B31: return AArch64::D31;202  }203  // For anything else, return it unchanged.204  return Reg;205}206 207static inline bool atomicBarrierDroppedOnZero(unsigned Opcode) {208  switch (Opcode) {209  case AArch64::LDADDAB:   case AArch64::LDADDAH:210  case AArch64::LDADDAW:   case AArch64::LDADDAX:211  case AArch64::LDADDALB:  case AArch64::LDADDALH:212  case AArch64::LDADDALW:  case AArch64::LDADDALX:213  case AArch64::LDCLRAB:   case AArch64::LDCLRAH:214  case AArch64::LDCLRAW:   case AArch64::LDCLRAX:215  case AArch64::LDCLRALB:  case AArch64::LDCLRALH:216  case AArch64::LDCLRALW:  case AArch64::LDCLRALX:217  case AArch64::LDEORAB:   case AArch64::LDEORAH:218  case AArch64::LDEORAW:   case AArch64::LDEORAX:219  case AArch64::LDEORALB:  case AArch64::LDEORALH:220  case AArch64::LDEORALW:  case AArch64::LDEORALX:221  case AArch64::LDSETAB:   case AArch64::LDSETAH:222  case AArch64::LDSETAW:   case AArch64::LDSETAX:223  case AArch64::LDSETALB:  case AArch64::LDSETALH:224  case AArch64::LDSETALW:  case AArch64::LDSETALX:225  case AArch64::LDSMAXAB:  case AArch64::LDSMAXAH:226  case AArch64::LDSMAXAW:  case AArch64::LDSMAXAX:227  case AArch64::LDSMAXALB: case AArch64::LDSMAXALH:228  case AArch64::LDSMAXALW: case AArch64::LDSMAXALX:229  case AArch64::LDSMINAB:  case AArch64::LDSMINAH:230  case AArch64::LDSMINAW:  case AArch64::LDSMINAX:231  case AArch64::LDSMINALB: case AArch64::LDSMINALH:232  case AArch64::LDSMINALW: case AArch64::LDSMINALX:233  case AArch64::LDUMAXAB:  case AArch64::LDUMAXAH:234  case AArch64::LDUMAXAW:  case AArch64::LDUMAXAX:235  case AArch64::LDUMAXALB: case AArch64::LDUMAXALH:236  case AArch64::LDUMAXALW: case AArch64::LDUMAXALX:237  case AArch64::LDUMINAB:  case AArch64::LDUMINAH:238  case AArch64::LDUMINAW:  case AArch64::LDUMINAX:239  case AArch64::LDUMINALB: case AArch64::LDUMINALH:240  case AArch64::LDUMINALW: case AArch64::LDUMINALX:241  case AArch64::SWPAB:     case AArch64::SWPAH:242  case AArch64::SWPAW:     case AArch64::SWPAX:243  case AArch64::SWPALB:    case AArch64::SWPALH:244  case AArch64::SWPALW:    case AArch64::SWPALX:245    return true;246  }247  return false;248}249 250namespace AArch64CC {251 252// The CondCodes constants map directly to the 4-bit encoding of the condition253// field for predicated instructions.254enum CondCode {  // Meaning (integer)          Meaning (floating-point)255  EQ = 0x0,      // Equal                      Equal256  NE = 0x1,      // Not equal                  Not equal, or unordered257  HS = 0x2,      // Unsigned higher or same    >, ==, or unordered258  LO = 0x3,      // Unsigned lower             Less than259  MI = 0x4,      // Minus, negative            Less than260  PL = 0x5,      // Plus, positive or zero     >, ==, or unordered261  VS = 0x6,      // Overflow                   Unordered262  VC = 0x7,      // No overflow                Not unordered263  HI = 0x8,      // Unsigned higher            Greater than, or unordered264  LS = 0x9,      // Unsigned lower or same     Less than or equal265  GE = 0xa,      // Greater than or equal      Greater than or equal266  LT = 0xb,      // Less than                  Less than, or unordered267  GT = 0xc,      // Greater than               Greater than268  LE = 0xd,      // Less than or equal         <, ==, or unordered269  AL = 0xe,      // Always (unconditional)     Always (unconditional)270  NV = 0xf,      // Always (unconditional)     Always (unconditional)271  // Note the NV exists purely to disassemble 0b1111. Execution is "always".272  Invalid,273 274  // Common aliases used for SVE.275  ANY_ACTIVE   = NE, // (!Z)276  FIRST_ACTIVE = MI, // ( N)277  LAST_ACTIVE  = LO, // (!C)278  NONE_ACTIVE  = EQ  // ( Z)279};280 281inline static const char *getCondCodeName(CondCode Code) {282  switch (Code) {283  default: llvm_unreachable("Unknown condition code");284  case EQ:  return "eq";285  case NE:  return "ne";286  case HS:  return "hs";287  case LO:  return "lo";288  case MI:  return "mi";289  case PL:  return "pl";290  case VS:  return "vs";291  case VC:  return "vc";292  case HI:  return "hi";293  case LS:  return "ls";294  case GE:  return "ge";295  case LT:  return "lt";296  case GT:  return "gt";297  case LE:  return "le";298  case AL:  return "al";299  case NV:  return "nv";300  }301}302 303inline static CondCode getInvertedCondCode(CondCode Code) {304  // To reverse a condition it's necessary to only invert the low bit:305 306  return static_cast<CondCode>(static_cast<unsigned>(Code) ^ 0x1);307}308 309/// getSwappedCondition - assume the flags are set by MI(a,b), return310/// the condition code if we modify the instructions such that flags are311/// set by MI(b,a).312inline static CondCode getSwappedCondition(CondCode CC) {313  switch (CC) {314  default:315    return AL;316  case EQ:317    return EQ;318  case NE:319    return NE;320  case HS:321    return LS;322  case LO:323    return HI;324  case HI:325    return LO;326  case LS:327    return HS;328  case GE:329    return LE;330  case LT:331    return GT;332  case GT:333    return LT;334  case LE:335    return GE;336  }337}338 339/// Given a condition code, return NZCV flags that would satisfy that condition.340/// The flag bits are in the format expected by the ccmp instructions.341/// Note that many different flag settings can satisfy a given condition code,342/// this function just returns one of them.343inline static unsigned getNZCVToSatisfyCondCode(CondCode Code) {344  // NZCV flags encoded as expected by ccmp instructions, ARMv8 ISA 5.5.7.345  enum { N = 8, Z = 4, C = 2, V = 1 };346  switch (Code) {347  default: llvm_unreachable("Unknown condition code");348  case EQ: return Z; // Z == 1349  case NE: return 0; // Z == 0350  case HS: return C; // C == 1351  case LO: return 0; // C == 0352  case MI: return N; // N == 1353  case PL: return 0; // N == 0354  case VS: return V; // V == 1355  case VC: return 0; // V == 0356  case HI: return C; // C == 1 && Z == 0357  case LS: return 0; // C == 0 || Z == 1358  case GE: return 0; // N == V359  case LT: return N; // N != V360  case GT: return 0; // Z == 0 && N == V361  case LE: return Z; // Z == 1 || N != V362  }363}364 365/// True, if a given condition code can be used in a fused compare-and-branch366/// instructions, false otherwise.367inline static bool isValidCBCond(AArch64CC::CondCode Code) {368  switch (Code) {369  default:370    return false;371  case AArch64CC::EQ:372  case AArch64CC::NE:373  case AArch64CC::HS:374  case AArch64CC::LO:375  case AArch64CC::HI:376  case AArch64CC::LS:377  case AArch64CC::GE:378  case AArch64CC::LT:379  case AArch64CC::GT:380  case AArch64CC::LE:381    return true;382  }383}384 385} // end namespace AArch64CC386 387struct SysAlias {388  const char *Name;389  uint16_t Encoding;390  FeatureBitset FeaturesRequired;391 392  constexpr SysAlias(const char *N, uint16_t E) : Name(N), Encoding(E) {}393  constexpr SysAlias(const char *N, uint16_t E, FeatureBitset F)394      : Name(N), Encoding(E), FeaturesRequired(F) {}395 396  bool haveFeatures(FeatureBitset ActiveFeatures) const {397    return ActiveFeatures[llvm::AArch64::FeatureAll] ||398           (FeaturesRequired & ActiveFeatures) == FeaturesRequired;399  }400 401  FeatureBitset getRequiredFeatures() const { return FeaturesRequired; }402};403 404struct SysAliasReg : SysAlias {405  bool NeedsReg;406  constexpr SysAliasReg(const char *N, uint16_t E, bool R)407      : SysAlias(N, E), NeedsReg(R) {}408  constexpr SysAliasReg(const char *N, uint16_t E, bool R, FeatureBitset F)409      : SysAlias(N, E, F), NeedsReg(R) {}410};411 412struct SysAliasOptionalReg : SysAlias {413  bool NeedsReg;414  bool OptionalReg;415  constexpr SysAliasOptionalReg(const char *N, uint16_t E, bool R, bool O)416      : SysAlias(N, E), NeedsReg(R), OptionalReg(O) {}417  constexpr SysAliasOptionalReg(const char *N, uint16_t E, bool R, bool O,418                                FeatureBitset F)419      : SysAlias(N, E, F), NeedsReg(R), OptionalReg(O) {}420};421 422struct SysAliasImm : SysAlias {423  uint16_t ImmValue;424  constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I)425      : SysAlias(N, E), ImmValue(I) {}426  constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I, FeatureBitset F)427      : SysAlias(N, E, F), ImmValue(I) {}428};429 430namespace AArch64SVCR {431  struct SVCR : SysAlias{432    using SysAlias::SysAlias;433  };434#define GET_SVCRValues_DECL435#define GET_SVCRsList_DECL436#include "AArch64GenSystemOperands.inc"437}438 439namespace AArch64AT{440  struct AT : SysAlias {441    using SysAlias::SysAlias;442  };443#define GET_ATValues_DECL444#define GET_ATsList_DECL445#include "AArch64GenSystemOperands.inc"446}447 448namespace AArch64DB {449  struct DB : SysAlias {450    using SysAlias::SysAlias;451  };452#define GET_DBValues_DECL453#define GET_DBsList_DECL454#include "AArch64GenSystemOperands.inc"455}456 457namespace AArch64DBnXS {458  struct DBnXS : SysAliasImm {459    using SysAliasImm::SysAliasImm;460  };461#define GET_DBnXSValues_DECL462#define GET_DBnXSsList_DECL463#include "AArch64GenSystemOperands.inc"464}465 466namespace  AArch64DC {467  struct DC : SysAlias {468    using SysAlias::SysAlias;469  };470#define GET_DCValues_DECL471#define GET_DCsList_DECL472#include "AArch64GenSystemOperands.inc"473}474 475namespace  AArch64IC {476  struct IC : SysAliasReg {477    using SysAliasReg::SysAliasReg;478  };479#define GET_ICValues_DECL480#define GET_ICsList_DECL481#include "AArch64GenSystemOperands.inc"482}483 484namespace  AArch64ISB {485  struct ISB : SysAlias {486    using SysAlias::SysAlias;487  };488#define GET_ISBValues_DECL489#define GET_ISBsList_DECL490#include "AArch64GenSystemOperands.inc"491}492 493namespace  AArch64TSB {494  struct TSB : SysAlias {495    using SysAlias::SysAlias;496  };497#define GET_TSBValues_DECL498#define GET_TSBsList_DECL499#include "AArch64GenSystemOperands.inc"500}501 502namespace AArch64PRFM {503  struct PRFM : SysAlias {504    using SysAlias::SysAlias;505  };506#define GET_PRFMValues_DECL507#define GET_PRFMsList_DECL508#include "AArch64GenSystemOperands.inc"509}510 511namespace AArch64SVEPRFM {512  struct SVEPRFM : SysAlias {513    using SysAlias::SysAlias;514  };515#define GET_SVEPRFMValues_DECL516#define GET_SVEPRFMsList_DECL517#include "AArch64GenSystemOperands.inc"518}519 520namespace AArch64RPRFM {521struct RPRFM : SysAlias {522  using SysAlias::SysAlias;523};524#define GET_RPRFMValues_DECL525#define GET_RPRFMsList_DECL526#include "AArch64GenSystemOperands.inc"527} // namespace AArch64RPRFM528 529namespace AArch64SVEPredPattern {530  struct SVEPREDPAT {531    const char *Name;532    uint16_t Encoding;533  };534#define GET_SVEPREDPATValues_DECL535#define GET_SVEPREDPATsList_DECL536#include "AArch64GenSystemOperands.inc"537}538 539namespace AArch64SVEVecLenSpecifier {540  struct SVEVECLENSPECIFIER {541    const char *Name;542    uint16_t Encoding;543  };544#define GET_SVEVECLENSPECIFIERValues_DECL545#define GET_SVEVECLENSPECIFIERsList_DECL546#include "AArch64GenSystemOperands.inc"547} // namespace AArch64SVEVecLenSpecifier548 549/// Return the number of active elements for VL1 to VL256 predicate pattern,550/// zero for all other patterns.551inline unsigned getNumElementsFromSVEPredPattern(unsigned Pattern) {552  switch (Pattern) {553  default:554    return 0;555  case AArch64SVEPredPattern::vl1:556  case AArch64SVEPredPattern::vl2:557  case AArch64SVEPredPattern::vl3:558  case AArch64SVEPredPattern::vl4:559  case AArch64SVEPredPattern::vl5:560  case AArch64SVEPredPattern::vl6:561  case AArch64SVEPredPattern::vl7:562  case AArch64SVEPredPattern::vl8:563    return Pattern;564  case AArch64SVEPredPattern::vl16:565    return 16;566  case AArch64SVEPredPattern::vl32:567    return 32;568  case AArch64SVEPredPattern::vl64:569    return 64;570  case AArch64SVEPredPattern::vl128:571    return 128;572  case AArch64SVEPredPattern::vl256:573    return 256;574  }575}576 577/// Return specific VL predicate pattern based on the number of elements.578inline std::optional<unsigned>579getSVEPredPatternFromNumElements(unsigned MinNumElts) {580  switch (MinNumElts) {581  default:582    return std::nullopt;583  case 1:584  case 2:585  case 3:586  case 4:587  case 5:588  case 6:589  case 7:590  case 8:591    return MinNumElts;592  case 16:593    return AArch64SVEPredPattern::vl16;594  case 32:595    return AArch64SVEPredPattern::vl32;596  case 64:597    return AArch64SVEPredPattern::vl64;598  case 128:599    return AArch64SVEPredPattern::vl128;600  case 256:601    return AArch64SVEPredPattern::vl256;602  }603}604 605/// An enum to describe what types of loops we should attempt to tail-fold:606///   Disabled:    None607///   Reductions:  Loops containing reductions608///   Recurrences: Loops with first-order recurrences, i.e. that would609///                  require a SVE splice instruction610///   Reverse:     Reverse loops611///   Simple:      Loops that are not reversed and don't contain reductions612///                  or first-order recurrences.613///   All:         All614enum class TailFoldingOpts : uint8_t {615  Disabled = 0x00,616  Simple = 0x01,617  Reductions = 0x02,618  Recurrences = 0x04,619  Reverse = 0x08,620  All = Reductions | Recurrences | Simple | Reverse621};622 623LLVM_DECLARE_ENUM_AS_BITMASK(TailFoldingOpts,624                             /* LargestValue */ (long)TailFoldingOpts::Reverse);625 626namespace AArch64ExactFPImm {627struct ExactFPImm {628  int Enum;629  const char *Repr;630};631#define GET_ExactFPImmValues_DECL632#define GET_ExactFPImmsList_DECL633#include "AArch64GenSystemOperands.inc"634}635 636namespace AArch64PState {637  struct PStateImm0_15 : SysAlias{638    using SysAlias::SysAlias;639  };640#define GET_PStateImm0_15Values_DECL641#define GET_PStateImm0_15sList_DECL642#include "AArch64GenSystemOperands.inc"643 644  struct PStateImm0_1 : SysAlias{645    using SysAlias::SysAlias;646  };647#define GET_PStateImm0_1Values_DECL648#define GET_PStateImm0_1sList_DECL649#include "AArch64GenSystemOperands.inc"650}651 652namespace AArch64PSBHint {653  struct PSB : SysAlias {654    using SysAlias::SysAlias;655  };656#define GET_PSBValues_DECL657#define GET_PSBsList_DECL658#include "AArch64GenSystemOperands.inc"659}660 661namespace AArch64PHint {662struct PHint {663  const char *Name;664  unsigned Encoding;665  FeatureBitset FeaturesRequired;666 667  bool haveFeatures(FeatureBitset ActiveFeatures) const {668    return ActiveFeatures[llvm::AArch64::FeatureAll] ||669           (FeaturesRequired & ActiveFeatures) == FeaturesRequired;670  }671};672 673#define GET_PHintValues_DECL674#define GET_PHintsList_DECL675#include "AArch64GenSystemOperands.inc"676 677const PHint *lookupPHintByName(StringRef);678const PHint *lookupPHintByEncoding(uint16_t);679} // namespace AArch64PHint680 681namespace AArch64BTIHint {682  struct BTI : SysAlias {683    using SysAlias::SysAlias;684  };685#define GET_BTIValues_DECL686#define GET_BTIsList_DECL687#include "AArch64GenSystemOperands.inc"688}689 690namespace AArch64CMHPriorityHint {691struct CMHPriorityHint : SysAlias {692  using SysAlias::SysAlias;693};694#define GET_CMHPRIORITYHINT_DECL695#include "AArch64GenSystemOperands.inc"696} // namespace AArch64CMHPriorityHint697 698namespace AArch64TIndexHint {699struct TIndex : SysAlias {700  using SysAlias::SysAlias;701};702#define GET_TINDEX_DECL703#include "AArch64GenSystemOperands.inc"704} // namespace AArch64TIndexHint705 706namespace AArch64SME {707enum ToggleCondition : unsigned {708  Always,709  IfCallerIsStreaming,710  IfCallerIsNonStreaming711};712}713 714namespace AArch64SE {715    enum ShiftExtSpecifiers {716        Invalid = -1,717        LSL,718        MSL,719        LSR,720        ASR,721        ROR,722 723        UXTB,724        UXTH,725        UXTW,726        UXTX,727 728        SXTB,729        SXTH,730        SXTW,731        SXTX732    };733}734 735namespace AArch64Layout {736    enum VectorLayout {737        Invalid = -1,738        VL_8B,739        VL_4H,740        VL_2S,741        VL_1D,742 743        VL_16B,744        VL_8H,745        VL_4S,746        VL_2D,747 748        // Bare layout for the 128-bit vector749        // (only show ".b", ".h", ".s", ".d" without vector number)750        VL_B,751        VL_H,752        VL_S,753        VL_D754    };755}756 757inline static const char *758AArch64VectorLayoutToString(AArch64Layout::VectorLayout Layout) {759  switch (Layout) {760  case AArch64Layout::VL_8B:  return ".8b";761  case AArch64Layout::VL_4H:  return ".4h";762  case AArch64Layout::VL_2S:  return ".2s";763  case AArch64Layout::VL_1D:  return ".1d";764  case AArch64Layout::VL_16B:  return ".16b";765  case AArch64Layout::VL_8H:  return ".8h";766  case AArch64Layout::VL_4S:  return ".4s";767  case AArch64Layout::VL_2D:  return ".2d";768  case AArch64Layout::VL_B:  return ".b";769  case AArch64Layout::VL_H:  return ".h";770  case AArch64Layout::VL_S:  return ".s";771  case AArch64Layout::VL_D:  return ".d";772  default: llvm_unreachable("Unknown Vector Layout");773  }774}775 776inline static AArch64Layout::VectorLayout777AArch64StringToVectorLayout(StringRef LayoutStr) {778  return StringSwitch<AArch64Layout::VectorLayout>(LayoutStr)779             .Case(".8b", AArch64Layout::VL_8B)780             .Case(".4h", AArch64Layout::VL_4H)781             .Case(".2s", AArch64Layout::VL_2S)782             .Case(".1d", AArch64Layout::VL_1D)783             .Case(".16b", AArch64Layout::VL_16B)784             .Case(".8h", AArch64Layout::VL_8H)785             .Case(".4s", AArch64Layout::VL_4S)786             .Case(".2d", AArch64Layout::VL_2D)787             .Case(".b", AArch64Layout::VL_B)788             .Case(".h", AArch64Layout::VL_H)789             .Case(".s", AArch64Layout::VL_S)790             .Case(".d", AArch64Layout::VL_D)791             .Default(AArch64Layout::Invalid);792}793 794namespace AArch64SysReg {795  struct SysReg {796    const char Name[32];797    unsigned Encoding;798    bool Readable;799    bool Writeable;800    FeatureBitset FeaturesRequired;801 802    bool haveFeatures(FeatureBitset ActiveFeatures) const {803      return ActiveFeatures[llvm::AArch64::FeatureAll] ||804             (FeaturesRequired & ActiveFeatures) == FeaturesRequired;805    }806  };807 808#define GET_SysRegsList_DECL809#define GET_SysRegValues_DECL810#include "AArch64GenSystemOperands.inc"811 812  uint32_t parseGenericRegister(StringRef Name);813  std::string genericRegisterString(uint32_t Bits);814}815 816namespace AArch64TLBI {817struct TLBI : SysAliasOptionalReg {818  using SysAliasOptionalReg::SysAliasOptionalReg;819};820#define GET_TLBITable_DECL821#include "AArch64GenSystemOperands.inc"822}823 824namespace AArch64TLBIP {825struct TLBIP : SysAliasOptionalReg {826  using SysAliasOptionalReg::SysAliasOptionalReg;827};828#define GET_TLBIPTable_DECL829#include "AArch64GenSystemOperands.inc"830} // namespace AArch64TLBIP831 832namespace AArch64MLBI {833struct MLBI : SysAliasReg {834  using SysAliasReg::SysAliasReg;835};836#define GET_MLBITable_DECL837#include "AArch64GenSystemOperands.inc"838} // namespace AArch64MLBI839 840namespace AArch64GIC {841struct GIC : SysAliasReg {842  using SysAliasReg::SysAliasReg;843};844#define GET_GICTable_DECL845#include "AArch64GenSystemOperands.inc"846} // namespace AArch64GIC847 848namespace AArch64GICR {849struct GICR : SysAliasReg {850  using SysAliasReg::SysAliasReg;851};852#define GET_GICRTable_DECL853#include "AArch64GenSystemOperands.inc"854} // namespace AArch64GICR855 856namespace AArch64GSB {857struct GSB : SysAlias {858  using SysAlias::SysAlias;859};860#define GET_GSBTable_DECL861#include "AArch64GenSystemOperands.inc"862} // namespace AArch64GSB863 864namespace AArch64PLBI {865struct PLBI : SysAliasOptionalReg {866  using SysAliasOptionalReg::SysAliasOptionalReg;867};868#define GET_PLBITable_DECL869#include "AArch64GenSystemOperands.inc"870} // namespace AArch64PLBI871 872namespace AArch64II {873/// Target Operand Flag enum.874enum TOF {875  //===------------------------------------------------------------------===//876  // AArch64 Specific MachineOperand flags.877 878  MO_NO_FLAG,879 880  MO_FRAGMENT = 0x7,881 882  /// MO_PAGE - A symbol operand with this flag represents the pc-relative883  /// offset of the 4K page containing the symbol.  This is used with the884  /// ADRP instruction.885  MO_PAGE = 1,886 887  /// MO_PAGEOFF - A symbol operand with this flag represents the offset of888  /// that symbol within a 4K page.  This offset is added to the page address889  /// to produce the complete address.890  MO_PAGEOFF = 2,891 892  /// MO_G3 - A symbol operand with this flag (granule 3) represents the high893  /// 16-bits of a 64-bit address, used in a MOVZ or MOVK instruction894  MO_G3 = 3,895 896  /// MO_G2 - A symbol operand with this flag (granule 2) represents the bits897  /// 32-47 of a 64-bit address, used in a MOVZ or MOVK instruction898  MO_G2 = 4,899 900  /// MO_G1 - A symbol operand with this flag (granule 1) represents the bits901  /// 16-31 of a 64-bit address, used in a MOVZ or MOVK instruction902  MO_G1 = 5,903 904  /// MO_G0 - A symbol operand with this flag (granule 0) represents the bits905  /// 0-15 of a 64-bit address, used in a MOVZ or MOVK instruction906  MO_G0 = 6,907 908  /// MO_HI12 - This flag indicates that a symbol operand represents the bits909  /// 13-24 of a 64-bit address, used in a arithmetic immediate-shifted-left-910  /// by-12-bits instruction.911  MO_HI12 = 7,912 913  /// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the914  /// reference is actually to the ".refptr.FOO" symbol.  This is used for915  /// stub symbols on windows.916  MO_COFFSTUB = 0x8,917 918  /// MO_GOT - This flag indicates that a symbol operand represents the919  /// address of the GOT entry for the symbol, rather than the address of920  /// the symbol itself.921  MO_GOT = 0x10,922 923  /// MO_NC - Indicates whether the linker is expected to check the symbol924  /// reference for overflow. For example in an ADRP/ADD pair of relocations925  /// the ADRP usually does check, but not the ADD.926  MO_NC = 0x20,927 928  /// MO_TLS - Indicates that the operand being accessed is some kind of929  /// thread-local symbol. On Darwin, only one type of thread-local access930  /// exists (pre linker-relaxation), but on ELF the TLSModel used for the931  /// referee will affect interpretation.932  MO_TLS = 0x40,933 934  /// MO_DLLIMPORT - On a symbol operand, this represents that the reference935  /// to the symbol is for an import stub.  This is used for DLL import936  /// storage class indication on Windows.937  MO_DLLIMPORT = 0x80,938 939  /// MO_S - Indicates that the bits of the symbol operand represented by940  /// MO_G0 etc are signed.941  MO_S = 0x100,942 943  /// MO_PREL - Indicates that the bits of the symbol operand represented by944  /// MO_G0 etc are PC relative.945  MO_PREL = 0x200,946 947  /// MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag948  /// in bits 56-63.949  /// On a FrameIndex operand, indicates that the underlying memory is tagged950  /// with an unknown tag value (MTE); this needs to be lowered either to an951  /// SP-relative load or store instruction (which do not check tags), or to952  /// an LDG instruction to obtain the tag value.953  MO_TAGGED = 0x400,954 955  /// MO_ARM64EC_CALLMANGLE - Operand refers to the Arm64EC-mangled version956  /// of a symbol, not the original. For dllimport symbols, this means it957  /// uses "__imp_aux".  For other symbols, this means it uses the mangled958  /// ("#" prefix for C) name.959  MO_ARM64EC_CALLMANGLE = 0x800,960};961} // end namespace AArch64II962 963//===----------------------------------------------------------------------===//964// v8.3a Pointer Authentication965//966 967namespace AArch64PACKey {968enum ID : uint8_t {969  IA = 0,970  IB = 1,971  DA = 2,972  DB = 3,973  LAST = DB974};975} // namespace AArch64PACKey976 977/// Return 2-letter identifier string for numeric key ID.978inline static StringRef AArch64PACKeyIDToString(AArch64PACKey::ID KeyID) {979  switch (KeyID) {980  case AArch64PACKey::IA:981    return StringRef("ia");982  case AArch64PACKey::IB:983    return StringRef("ib");984  case AArch64PACKey::DA:985    return StringRef("da");986  case AArch64PACKey::DB:987    return StringRef("db");988  }989  llvm_unreachable("Unhandled AArch64PACKey::ID enum");990}991 992/// Return numeric key ID for 2-letter identifier string.993inline static std::optional<AArch64PACKey::ID>994AArch64StringToPACKeyID(StringRef Name) {995  if (Name == "ia")996    return AArch64PACKey::IA;997  if (Name == "ib")998    return AArch64PACKey::IB;999  if (Name == "da")1000    return AArch64PACKey::DA;1001  if (Name == "db")1002    return AArch64PACKey::DB;1003  return std::nullopt;1004}1005 1006inline static unsigned getBTIHintNum(bool CallTarget, bool JumpTarget) {1007  unsigned HintNum = 32;1008  if (CallTarget)1009    HintNum |= 2;1010  if (JumpTarget)1011    HintNum |= 4;1012  assert(HintNum != 32 && "No target kinds!");1013  return HintNum;1014}1015 1016namespace AArch64 {1017// The number of bits in a SVE register is architecturally defined1018// to be a multiple of this value.  If <M x t> has this number of bits,1019// a <n x M x t> vector can be stored in a SVE register without any1020// redundant bits.  If <M x t> has this number of bits divided by P,1021// a <n x M x t> vector is stored in a SVE register by placing index i1022// in index i*P of a <n x (M*P) x t> vector.  The other elements of the1023// <n x (M*P) x t> vector (such as index 1) are undefined.1024static constexpr unsigned SVEBitsPerBlock = 128;1025static constexpr unsigned SVEMaxBitsPerVector = 2048;1026} // end namespace AArch641027} // end namespace llvm1028 1029#endif1030