2014-05-24 14:50:23 +02:00
|
|
|
//===-- AArch64BaseInfo.h - Top level definitions for AArch64 ---*- C++ -*-===//
|
2014-03-29 11:18:08 +01:00
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2014-03-29 11:18:08 +01:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains small standalone helper functions and enum definitions for
|
2014-05-24 14:50:23 +02:00
|
|
|
// the AArch64 target useful for the compiler back-end and the MC libraries.
|
2014-03-29 11:18:08 +01:00
|
|
|
// As such, it deliberately does not include references to LLVM core
|
|
|
|
// code gen types, passes, etc..
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-08-13 18:26:38 +02:00
|
|
|
#ifndef LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64BASEINFO_H
|
|
|
|
#define LLVM_LIB_TARGET_AARCH64_UTILS_AARCH64BASEINFO_H
|
2014-03-29 11:18:08 +01:00
|
|
|
|
2014-04-09 16:42:27 +02:00
|
|
|
// FIXME: Is it easiest to fix this layering violation by moving the .inc
|
2014-05-24 14:50:23 +02:00
|
|
|
// #includes from AArch64MCTargetDesc.h to here?
|
|
|
|
#include "MCTargetDesc/AArch64MCTargetDesc.h" // For AArch64::X0 and friends.
|
2014-04-09 16:42:16 +02:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2015-05-26 12:47:10 +02:00
|
|
|
#include "llvm/MC/SubtargetFeature.h"
|
2014-03-29 11:18:08 +01:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
|
|
|
inline static unsigned getWRegFromXReg(unsigned Reg) {
|
|
|
|
switch (Reg) {
|
2014-05-24 14:50:23 +02:00
|
|
|
case AArch64::X0: return AArch64::W0;
|
|
|
|
case AArch64::X1: return AArch64::W1;
|
|
|
|
case AArch64::X2: return AArch64::W2;
|
|
|
|
case AArch64::X3: return AArch64::W3;
|
|
|
|
case AArch64::X4: return AArch64::W4;
|
|
|
|
case AArch64::X5: return AArch64::W5;
|
|
|
|
case AArch64::X6: return AArch64::W6;
|
|
|
|
case AArch64::X7: return AArch64::W7;
|
|
|
|
case AArch64::X8: return AArch64::W8;
|
|
|
|
case AArch64::X9: return AArch64::W9;
|
|
|
|
case AArch64::X10: return AArch64::W10;
|
|
|
|
case AArch64::X11: return AArch64::W11;
|
|
|
|
case AArch64::X12: return AArch64::W12;
|
|
|
|
case AArch64::X13: return AArch64::W13;
|
|
|
|
case AArch64::X14: return AArch64::W14;
|
|
|
|
case AArch64::X15: return AArch64::W15;
|
|
|
|
case AArch64::X16: return AArch64::W16;
|
|
|
|
case AArch64::X17: return AArch64::W17;
|
|
|
|
case AArch64::X18: return AArch64::W18;
|
|
|
|
case AArch64::X19: return AArch64::W19;
|
|
|
|
case AArch64::X20: return AArch64::W20;
|
|
|
|
case AArch64::X21: return AArch64::W21;
|
|
|
|
case AArch64::X22: return AArch64::W22;
|
|
|
|
case AArch64::X23: return AArch64::W23;
|
|
|
|
case AArch64::X24: return AArch64::W24;
|
|
|
|
case AArch64::X25: return AArch64::W25;
|
|
|
|
case AArch64::X26: return AArch64::W26;
|
|
|
|
case AArch64::X27: return AArch64::W27;
|
|
|
|
case AArch64::X28: return AArch64::W28;
|
|
|
|
case AArch64::FP: return AArch64::W29;
|
|
|
|
case AArch64::LR: return AArch64::W30;
|
|
|
|
case AArch64::SP: return AArch64::WSP;
|
|
|
|
case AArch64::XZR: return AArch64::WZR;
|
2014-03-29 11:18:08 +01:00
|
|
|
}
|
|
|
|
// For anything else, return it unchanged.
|
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline static unsigned getXRegFromWReg(unsigned Reg) {
|
|
|
|
switch (Reg) {
|
2014-05-24 14:50:23 +02:00
|
|
|
case AArch64::W0: return AArch64::X0;
|
|
|
|
case AArch64::W1: return AArch64::X1;
|
|
|
|
case AArch64::W2: return AArch64::X2;
|
|
|
|
case AArch64::W3: return AArch64::X3;
|
|
|
|
case AArch64::W4: return AArch64::X4;
|
|
|
|
case AArch64::W5: return AArch64::X5;
|
|
|
|
case AArch64::W6: return AArch64::X6;
|
|
|
|
case AArch64::W7: return AArch64::X7;
|
|
|
|
case AArch64::W8: return AArch64::X8;
|
|
|
|
case AArch64::W9: return AArch64::X9;
|
|
|
|
case AArch64::W10: return AArch64::X10;
|
|
|
|
case AArch64::W11: return AArch64::X11;
|
|
|
|
case AArch64::W12: return AArch64::X12;
|
|
|
|
case AArch64::W13: return AArch64::X13;
|
|
|
|
case AArch64::W14: return AArch64::X14;
|
|
|
|
case AArch64::W15: return AArch64::X15;
|
|
|
|
case AArch64::W16: return AArch64::X16;
|
|
|
|
case AArch64::W17: return AArch64::X17;
|
|
|
|
case AArch64::W18: return AArch64::X18;
|
|
|
|
case AArch64::W19: return AArch64::X19;
|
|
|
|
case AArch64::W20: return AArch64::X20;
|
|
|
|
case AArch64::W21: return AArch64::X21;
|
|
|
|
case AArch64::W22: return AArch64::X22;
|
|
|
|
case AArch64::W23: return AArch64::X23;
|
|
|
|
case AArch64::W24: return AArch64::X24;
|
|
|
|
case AArch64::W25: return AArch64::X25;
|
|
|
|
case AArch64::W26: return AArch64::X26;
|
|
|
|
case AArch64::W27: return AArch64::X27;
|
|
|
|
case AArch64::W28: return AArch64::X28;
|
|
|
|
case AArch64::W29: return AArch64::FP;
|
|
|
|
case AArch64::W30: return AArch64::LR;
|
|
|
|
case AArch64::WSP: return AArch64::SP;
|
|
|
|
case AArch64::WZR: return AArch64::XZR;
|
2014-03-29 11:18:08 +01:00
|
|
|
}
|
|
|
|
// For anything else, return it unchanged.
|
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
|
2021-07-31 09:59:19 +02:00
|
|
|
inline static unsigned getXRegFromXRegTuple(unsigned RegTuple) {
|
|
|
|
switch (RegTuple) {
|
|
|
|
case AArch64::X0_X1_X2_X3_X4_X5_X6_X7: return AArch64::X0;
|
|
|
|
case AArch64::X2_X3_X4_X5_X6_X7_X8_X9: return AArch64::X2;
|
|
|
|
case AArch64::X4_X5_X6_X7_X8_X9_X10_X11: return AArch64::X4;
|
|
|
|
case AArch64::X6_X7_X8_X9_X10_X11_X12_X13: return AArch64::X6;
|
|
|
|
case AArch64::X8_X9_X10_X11_X12_X13_X14_X15: return AArch64::X8;
|
|
|
|
case AArch64::X10_X11_X12_X13_X14_X15_X16_X17: return AArch64::X10;
|
|
|
|
case AArch64::X12_X13_X14_X15_X16_X17_X18_X19: return AArch64::X12;
|
|
|
|
case AArch64::X14_X15_X16_X17_X18_X19_X20_X21: return AArch64::X14;
|
|
|
|
case AArch64::X16_X17_X18_X19_X20_X21_X22_X23: return AArch64::X16;
|
|
|
|
case AArch64::X18_X19_X20_X21_X22_X23_X24_X25: return AArch64::X18;
|
|
|
|
case AArch64::X20_X21_X22_X23_X24_X25_X26_X27: return AArch64::X20;
|
|
|
|
case AArch64::X22_X23_X24_X25_X26_X27_X28_FP: return AArch64::X22;
|
|
|
|
}
|
|
|
|
// For anything else, return it unchanged.
|
|
|
|
return RegTuple;
|
|
|
|
}
|
|
|
|
|
2014-03-29 11:18:08 +01:00
|
|
|
static inline unsigned getBRegFromDReg(unsigned Reg) {
|
|
|
|
switch (Reg) {
|
2014-05-24 14:50:23 +02:00
|
|
|
case AArch64::D0: return AArch64::B0;
|
|
|
|
case AArch64::D1: return AArch64::B1;
|
|
|
|
case AArch64::D2: return AArch64::B2;
|
|
|
|
case AArch64::D3: return AArch64::B3;
|
|
|
|
case AArch64::D4: return AArch64::B4;
|
|
|
|
case AArch64::D5: return AArch64::B5;
|
|
|
|
case AArch64::D6: return AArch64::B6;
|
|
|
|
case AArch64::D7: return AArch64::B7;
|
|
|
|
case AArch64::D8: return AArch64::B8;
|
|
|
|
case AArch64::D9: return AArch64::B9;
|
|
|
|
case AArch64::D10: return AArch64::B10;
|
|
|
|
case AArch64::D11: return AArch64::B11;
|
|
|
|
case AArch64::D12: return AArch64::B12;
|
|
|
|
case AArch64::D13: return AArch64::B13;
|
|
|
|
case AArch64::D14: return AArch64::B14;
|
|
|
|
case AArch64::D15: return AArch64::B15;
|
|
|
|
case AArch64::D16: return AArch64::B16;
|
|
|
|
case AArch64::D17: return AArch64::B17;
|
|
|
|
case AArch64::D18: return AArch64::B18;
|
|
|
|
case AArch64::D19: return AArch64::B19;
|
|
|
|
case AArch64::D20: return AArch64::B20;
|
|
|
|
case AArch64::D21: return AArch64::B21;
|
|
|
|
case AArch64::D22: return AArch64::B22;
|
|
|
|
case AArch64::D23: return AArch64::B23;
|
|
|
|
case AArch64::D24: return AArch64::B24;
|
|
|
|
case AArch64::D25: return AArch64::B25;
|
|
|
|
case AArch64::D26: return AArch64::B26;
|
|
|
|
case AArch64::D27: return AArch64::B27;
|
|
|
|
case AArch64::D28: return AArch64::B28;
|
|
|
|
case AArch64::D29: return AArch64::B29;
|
|
|
|
case AArch64::D30: return AArch64::B30;
|
|
|
|
case AArch64::D31: return AArch64::B31;
|
2014-03-29 11:18:08 +01:00
|
|
|
}
|
|
|
|
// For anything else, return it unchanged.
|
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline unsigned getDRegFromBReg(unsigned Reg) {
|
|
|
|
switch (Reg) {
|
2014-05-24 14:50:23 +02:00
|
|
|
case AArch64::B0: return AArch64::D0;
|
|
|
|
case AArch64::B1: return AArch64::D1;
|
|
|
|
case AArch64::B2: return AArch64::D2;
|
|
|
|
case AArch64::B3: return AArch64::D3;
|
|
|
|
case AArch64::B4: return AArch64::D4;
|
|
|
|
case AArch64::B5: return AArch64::D5;
|
|
|
|
case AArch64::B6: return AArch64::D6;
|
|
|
|
case AArch64::B7: return AArch64::D7;
|
|
|
|
case AArch64::B8: return AArch64::D8;
|
|
|
|
case AArch64::B9: return AArch64::D9;
|
|
|
|
case AArch64::B10: return AArch64::D10;
|
|
|
|
case AArch64::B11: return AArch64::D11;
|
|
|
|
case AArch64::B12: return AArch64::D12;
|
|
|
|
case AArch64::B13: return AArch64::D13;
|
|
|
|
case AArch64::B14: return AArch64::D14;
|
|
|
|
case AArch64::B15: return AArch64::D15;
|
|
|
|
case AArch64::B16: return AArch64::D16;
|
|
|
|
case AArch64::B17: return AArch64::D17;
|
|
|
|
case AArch64::B18: return AArch64::D18;
|
|
|
|
case AArch64::B19: return AArch64::D19;
|
|
|
|
case AArch64::B20: return AArch64::D20;
|
|
|
|
case AArch64::B21: return AArch64::D21;
|
|
|
|
case AArch64::B22: return AArch64::D22;
|
|
|
|
case AArch64::B23: return AArch64::D23;
|
|
|
|
case AArch64::B24: return AArch64::D24;
|
|
|
|
case AArch64::B25: return AArch64::D25;
|
|
|
|
case AArch64::B26: return AArch64::D26;
|
|
|
|
case AArch64::B27: return AArch64::D27;
|
|
|
|
case AArch64::B28: return AArch64::D28;
|
|
|
|
case AArch64::B29: return AArch64::D29;
|
|
|
|
case AArch64::B30: return AArch64::D30;
|
|
|
|
case AArch64::B31: return AArch64::D31;
|
2014-03-29 11:18:08 +01:00
|
|
|
}
|
|
|
|
// For anything else, return it unchanged.
|
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
|
2019-02-06 16:07:59 +01:00
|
|
|
static inline bool atomicBarrierDroppedOnZero(unsigned Opcode) {
|
|
|
|
switch (Opcode) {
|
|
|
|
case AArch64::LDADDAB: case AArch64::LDADDAH:
|
|
|
|
case AArch64::LDADDAW: case AArch64::LDADDAX:
|
|
|
|
case AArch64::LDADDALB: case AArch64::LDADDALH:
|
|
|
|
case AArch64::LDADDALW: case AArch64::LDADDALX:
|
|
|
|
case AArch64::LDCLRAB: case AArch64::LDCLRAH:
|
|
|
|
case AArch64::LDCLRAW: case AArch64::LDCLRAX:
|
|
|
|
case AArch64::LDCLRALB: case AArch64::LDCLRALH:
|
|
|
|
case AArch64::LDCLRALW: case AArch64::LDCLRALX:
|
|
|
|
case AArch64::LDEORAB: case AArch64::LDEORAH:
|
|
|
|
case AArch64::LDEORAW: case AArch64::LDEORAX:
|
|
|
|
case AArch64::LDEORALB: case AArch64::LDEORALH:
|
|
|
|
case AArch64::LDEORALW: case AArch64::LDEORALX:
|
|
|
|
case AArch64::LDSETAB: case AArch64::LDSETAH:
|
|
|
|
case AArch64::LDSETAW: case AArch64::LDSETAX:
|
|
|
|
case AArch64::LDSETALB: case AArch64::LDSETALH:
|
|
|
|
case AArch64::LDSETALW: case AArch64::LDSETALX:
|
|
|
|
case AArch64::LDSMAXAB: case AArch64::LDSMAXAH:
|
|
|
|
case AArch64::LDSMAXAW: case AArch64::LDSMAXAX:
|
|
|
|
case AArch64::LDSMAXALB: case AArch64::LDSMAXALH:
|
|
|
|
case AArch64::LDSMAXALW: case AArch64::LDSMAXALX:
|
|
|
|
case AArch64::LDSMINAB: case AArch64::LDSMINAH:
|
|
|
|
case AArch64::LDSMINAW: case AArch64::LDSMINAX:
|
|
|
|
case AArch64::LDSMINALB: case AArch64::LDSMINALH:
|
|
|
|
case AArch64::LDSMINALW: case AArch64::LDSMINALX:
|
|
|
|
case AArch64::LDUMAXAB: case AArch64::LDUMAXAH:
|
|
|
|
case AArch64::LDUMAXAW: case AArch64::LDUMAXAX:
|
|
|
|
case AArch64::LDUMAXALB: case AArch64::LDUMAXALH:
|
|
|
|
case AArch64::LDUMAXALW: case AArch64::LDUMAXALX:
|
|
|
|
case AArch64::LDUMINAB: case AArch64::LDUMINAH:
|
|
|
|
case AArch64::LDUMINAW: case AArch64::LDUMINAX:
|
|
|
|
case AArch64::LDUMINALB: case AArch64::LDUMINALH:
|
|
|
|
case AArch64::LDUMINALW: case AArch64::LDUMINALX:
|
|
|
|
case AArch64::SWPAB: case AArch64::SWPAH:
|
|
|
|
case AArch64::SWPAW: case AArch64::SWPAX:
|
|
|
|
case AArch64::SWPALB: case AArch64::SWPALH:
|
|
|
|
case AArch64::SWPALW: case AArch64::SWPALX:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64CC {
|
2014-03-29 11:18:08 +01:00
|
|
|
|
|
|
|
// The CondCodes constants map directly to the 4-bit encoding of the condition
|
|
|
|
// field for predicated instructions.
|
|
|
|
enum CondCode { // Meaning (integer) Meaning (floating-point)
|
|
|
|
EQ = 0x0, // Equal Equal
|
|
|
|
NE = 0x1, // Not equal Not equal, or unordered
|
2014-04-30 15:14:03 +02:00
|
|
|
HS = 0x2, // Unsigned higher or same >, ==, or unordered
|
|
|
|
LO = 0x3, // Unsigned lower Less than
|
2014-03-29 11:18:08 +01:00
|
|
|
MI = 0x4, // Minus, negative Less than
|
|
|
|
PL = 0x5, // Plus, positive or zero >, ==, or unordered
|
|
|
|
VS = 0x6, // Overflow Unordered
|
|
|
|
VC = 0x7, // No overflow Not unordered
|
|
|
|
HI = 0x8, // Unsigned higher Greater than, or unordered
|
|
|
|
LS = 0x9, // Unsigned lower or same Less than or equal
|
|
|
|
GE = 0xa, // Greater than or equal Greater than or equal
|
|
|
|
LT = 0xb, // Less than Less than, or unordered
|
|
|
|
GT = 0xc, // Greater than Greater than
|
|
|
|
LE = 0xd, // Less than or equal <, ==, or unordered
|
2014-04-09 16:42:07 +02:00
|
|
|
AL = 0xe, // Always (unconditional) Always (unconditional)
|
|
|
|
NV = 0xf, // Always (unconditional) Always (unconditional)
|
|
|
|
// Note the NV exists purely to disassemble 0b1111. Execution is "always".
|
[AArch64][SVE] Add ptest intrinsics
Summary:
Implements the following intrinsics:
* @llvm.aarch64.sve.ptest.any
* @llvm.aarch64.sve.ptest.first
* @llvm.aarch64.sve.ptest.last
Reviewers: sdesmalen, efriedma, dancgr, mgudim, cameron.mcinally, rengolin
Reviewed By: efriedma
Subscribers: tschuett, kristof.beyls, hiraditya, rkruppe, psnobl, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D72398
2020-01-08 15:25:20 +01:00
|
|
|
Invalid,
|
|
|
|
|
|
|
|
// Common aliases used for SVE.
|
|
|
|
ANY_ACTIVE = NE, // (!Z)
|
|
|
|
FIRST_ACTIVE = MI, // ( N)
|
|
|
|
LAST_ACTIVE = LO, // (!C)
|
|
|
|
NONE_ACTIVE = EQ // ( Z)
|
2014-03-29 11:18:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
inline static const char *getCondCodeName(CondCode Code) {
|
|
|
|
switch (Code) {
|
2014-04-09 16:42:07 +02:00
|
|
|
default: llvm_unreachable("Unknown condition code");
|
2014-03-29 11:18:08 +01:00
|
|
|
case EQ: return "eq";
|
|
|
|
case NE: return "ne";
|
2014-04-30 15:14:03 +02:00
|
|
|
case HS: return "hs";
|
|
|
|
case LO: return "lo";
|
2014-03-29 11:18:08 +01:00
|
|
|
case MI: return "mi";
|
|
|
|
case PL: return "pl";
|
|
|
|
case VS: return "vs";
|
|
|
|
case VC: return "vc";
|
|
|
|
case HI: return "hi";
|
|
|
|
case LS: return "ls";
|
|
|
|
case GE: return "ge";
|
|
|
|
case LT: return "lt";
|
|
|
|
case GT: return "gt";
|
|
|
|
case LE: return "le";
|
|
|
|
case AL: return "al";
|
2014-04-09 16:42:07 +02:00
|
|
|
case NV: return "nv";
|
2014-03-29 11:18:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline static CondCode getInvertedCondCode(CondCode Code) {
|
2014-05-29 13:34:50 +02:00
|
|
|
// To reverse a condition it's necessary to only invert the low bit:
|
|
|
|
|
|
|
|
return static_cast<CondCode>(static_cast<unsigned>(Code) ^ 0x1);
|
2014-03-29 11:18:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Given a condition code, return NZCV flags that would satisfy that condition.
|
|
|
|
/// The flag bits are in the format expected by the ccmp instructions.
|
|
|
|
/// Note that many different flag settings can satisfy a given condition code,
|
|
|
|
/// this function just returns one of them.
|
|
|
|
inline static unsigned getNZCVToSatisfyCondCode(CondCode Code) {
|
|
|
|
// NZCV flags encoded as expected by ccmp instructions, ARMv8 ISA 5.5.7.
|
|
|
|
enum { N = 8, Z = 4, C = 2, V = 1 };
|
|
|
|
switch (Code) {
|
|
|
|
default: llvm_unreachable("Unknown condition code");
|
|
|
|
case EQ: return Z; // Z == 1
|
|
|
|
case NE: return 0; // Z == 0
|
2014-04-30 15:14:03 +02:00
|
|
|
case HS: return C; // C == 1
|
|
|
|
case LO: return 0; // C == 0
|
2014-03-29 11:18:08 +01:00
|
|
|
case MI: return N; // N == 1
|
|
|
|
case PL: return 0; // N == 0
|
|
|
|
case VS: return V; // V == 1
|
|
|
|
case VC: return 0; // V == 0
|
|
|
|
case HI: return C; // C == 1 && Z == 0
|
|
|
|
case LS: return 0; // C == 0 || Z == 1
|
|
|
|
case GE: return 0; // N == V
|
|
|
|
case LT: return N; // N != V
|
|
|
|
case GT: return 0; // Z == 0 && N == V
|
|
|
|
case LE: return Z; // Z == 1 || N != V
|
|
|
|
}
|
|
|
|
}
|
2014-05-24 14:50:23 +02:00
|
|
|
} // end namespace AArch64CC
|
2014-03-29 11:18:08 +01:00
|
|
|
|
2017-02-27 15:45:34 +01:00
|
|
|
struct SysAlias {
|
|
|
|
const char *Name;
|
|
|
|
uint16_t Encoding;
|
|
|
|
FeatureBitset FeaturesRequired;
|
|
|
|
|
2019-08-24 17:02:44 +02:00
|
|
|
constexpr SysAlias(const char *N, uint16_t E) : Name(N), Encoding(E) {}
|
|
|
|
constexpr SysAlias(const char *N, uint16_t E, FeatureBitset F)
|
|
|
|
: Name(N), Encoding(E), FeaturesRequired(F) {}
|
2017-02-27 15:45:34 +01:00
|
|
|
|
|
|
|
bool haveFeatures(FeatureBitset ActiveFeatures) const {
|
|
|
|
return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
|
|
|
|
}
|
2017-03-03 09:12:47 +01:00
|
|
|
|
|
|
|
FeatureBitset getRequiredFeatures() const { return FeaturesRequired; }
|
2017-02-27 15:45:34 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct SysAliasReg : SysAlias {
|
|
|
|
bool NeedsReg;
|
2019-08-24 17:02:44 +02:00
|
|
|
constexpr SysAliasReg(const char *N, uint16_t E, bool R)
|
|
|
|
: SysAlias(N, E), NeedsReg(R) {}
|
|
|
|
constexpr SysAliasReg(const char *N, uint16_t E, bool R, FeatureBitset F)
|
|
|
|
: SysAlias(N, E, F), NeedsReg(R) {}
|
2017-02-27 15:45:34 +01:00
|
|
|
};
|
|
|
|
|
2020-11-12 10:50:58 +01:00
|
|
|
struct SysAliasImm : SysAlias {
|
|
|
|
uint16_t ImmValue;
|
|
|
|
constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I)
|
|
|
|
: SysAlias(N, E), ImmValue(I) {}
|
|
|
|
constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I, FeatureBitset F)
|
|
|
|
: SysAlias(N, E, F), ImmValue(I) {}
|
|
|
|
};
|
|
|
|
|
[AArch64][SME] Add system registers and related instructions
This patch adds the new system registers introduced in SME:
- ID_AA64SMFR0_EL1 (ro) SME feature identifier.
- SMCR_ELx (r/w) streaming mode control register for configuring
effective SVE Streaming SVE Vector length when the PE is in
Streaming SVE mode.
- SVCR (r/w) streaming vector control register, visible at all
exception levels. Provides access to PSTATE.SM and PSTATE.ZA
using MSR and MRS instructions.
- SMPRI_EL1 (r/w) streaming mode execution priority register.
- SMPRIMAP_EL2 (r/w) streaming mode priority mapping register.
- SMIDR_EL1 (ro) streaming mode identification register.
- TPIDR2_EL0 (r/w) for use by SME software to manage per-thread
SME context.
- MPAMSM_EL1 (r/w) MPAM (v8.4) streaming mode register, for
labelling memory accesses performed in streaming mode.
Also added in this patch are the SME mode change instructions.
Three MSR immediate instructions are implemented to set or clear
PSTATE.SM, PSTATE.ZA, or both respectively:
- MSR SVCRSM, #<imm1>
- MSR SVCRZA, #<imm1>
- MSR SVCRSMZA, #<imm1>
The following smstart/smstop aliases are also implemented for
convenience:
smstart -> MSR SVCRSMZA, #1
smstart sm -> MSR SVCRSM, #1
smstart za -> MSR SVCRZA, #1
smstop -> MSR SVCRSMZA, #0
smstop sm -> MSR SVCRSM, #0
smstop za -> MSR SVCRZA, #0
The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2021-06
Reviewed By: david-arm
Differential Revision: https://reviews.llvm.org/D105576
2021-07-20 09:19:10 +02:00
|
|
|
namespace AArch64SVCR {
|
|
|
|
struct SVCR : SysAlias{
|
|
|
|
using SysAlias::SysAlias;
|
|
|
|
};
|
|
|
|
#define GET_SVCR_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
|
|
|
}
|
|
|
|
|
2016-07-05 23:23:04 +02:00
|
|
|
namespace AArch64AT{
|
2017-02-27 15:45:34 +01:00
|
|
|
struct AT : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_AT_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2017-02-27 15:45:34 +01:00
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64DB {
|
2017-02-27 15:45:34 +01:00
|
|
|
struct DB : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_DB_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2020-11-12 10:50:58 +01:00
|
|
|
namespace AArch64DBnXS {
|
|
|
|
struct DBnXS : SysAliasImm {
|
|
|
|
using SysAliasImm::SysAliasImm;
|
|
|
|
};
|
|
|
|
#define GET_DBNXS_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
|
|
|
}
|
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64DC {
|
2017-02-27 15:45:34 +01:00
|
|
|
struct DC : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_DC_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64IC {
|
2017-02-27 15:45:34 +01:00
|
|
|
struct IC : SysAliasReg {
|
|
|
|
using SysAliasReg::SysAliasReg;
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_IC_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64ISB {
|
2017-02-27 15:45:34 +01:00
|
|
|
struct ISB : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_ISB_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2018-07-06 10:03:12 +02:00
|
|
|
namespace AArch64TSB {
|
|
|
|
struct TSB : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
|
|
|
};
|
|
|
|
#define GET_TSB_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
|
|
|
}
|
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64PRFM {
|
2017-02-27 15:45:34 +01:00
|
|
|
struct PRFM : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_PRFM_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2018-05-14 13:54:41 +02:00
|
|
|
namespace AArch64SVEPRFM {
|
|
|
|
struct SVEPRFM : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
|
|
|
};
|
|
|
|
#define GET_SVEPRFM_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
|
|
|
}
|
|
|
|
|
2018-01-22 11:46:00 +01:00
|
|
|
namespace AArch64SVEPredPattern {
|
|
|
|
struct SVEPREDPAT {
|
|
|
|
const char *Name;
|
|
|
|
uint16_t Encoding;
|
|
|
|
};
|
|
|
|
#define GET_SVEPREDPAT_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
|
|
|
}
|
|
|
|
|
2018-06-15 15:11:49 +02:00
|
|
|
namespace AArch64ExactFPImm {
|
|
|
|
struct ExactFPImm {
|
|
|
|
const char *Name;
|
|
|
|
int Enum;
|
|
|
|
const char *Repr;
|
|
|
|
};
|
|
|
|
#define GET_EXACTFPIMM_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
|
|
|
}
|
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64PState {
|
2017-02-27 15:45:34 +01:00
|
|
|
struct PState : SysAlias{
|
|
|
|
using SysAlias::SysAlias;
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_PSTATE_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2015-12-01 11:48:51 +01:00
|
|
|
namespace AArch64PSBHint {
|
2017-02-27 15:45:34 +01:00
|
|
|
struct PSB : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
2015-12-01 11:48:51 +01:00
|
|
|
};
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_PSB_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2015-12-01 11:48:51 +01:00
|
|
|
}
|
|
|
|
|
2018-09-27 16:54:33 +02:00
|
|
|
namespace AArch64BTIHint {
|
|
|
|
struct BTI : SysAlias {
|
|
|
|
using SysAlias::SysAlias;
|
|
|
|
};
|
|
|
|
#define GET_BTI_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
|
|
|
}
|
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64SE {
|
2014-04-09 16:42:16 +02:00
|
|
|
enum ShiftExtSpecifiers {
|
|
|
|
Invalid = -1,
|
|
|
|
LSL,
|
|
|
|
MSL,
|
|
|
|
LSR,
|
|
|
|
ASR,
|
|
|
|
ROR,
|
|
|
|
|
|
|
|
UXTB,
|
|
|
|
UXTH,
|
|
|
|
UXTW,
|
|
|
|
UXTX,
|
|
|
|
|
|
|
|
SXTB,
|
|
|
|
SXTH,
|
|
|
|
SXTW,
|
|
|
|
SXTX
|
|
|
|
};
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64Layout {
|
2014-04-09 16:42:16 +02:00
|
|
|
enum VectorLayout {
|
|
|
|
Invalid = -1,
|
|
|
|
VL_8B,
|
|
|
|
VL_4H,
|
|
|
|
VL_2S,
|
|
|
|
VL_1D,
|
|
|
|
|
|
|
|
VL_16B,
|
|
|
|
VL_8H,
|
|
|
|
VL_4S,
|
|
|
|
VL_2D,
|
|
|
|
|
|
|
|
// Bare layout for the 128-bit vector
|
|
|
|
// (only show ".b", ".h", ".s", ".d" without vector number)
|
|
|
|
VL_B,
|
|
|
|
VL_H,
|
|
|
|
VL_S,
|
|
|
|
VL_D
|
|
|
|
};
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
|
|
|
inline static const char *
|
2014-05-24 14:50:23 +02:00
|
|
|
AArch64VectorLayoutToString(AArch64Layout::VectorLayout Layout) {
|
2014-04-09 16:42:16 +02:00
|
|
|
switch (Layout) {
|
2014-05-24 14:50:23 +02:00
|
|
|
case AArch64Layout::VL_8B: return ".8b";
|
|
|
|
case AArch64Layout::VL_4H: return ".4h";
|
|
|
|
case AArch64Layout::VL_2S: return ".2s";
|
|
|
|
case AArch64Layout::VL_1D: return ".1d";
|
|
|
|
case AArch64Layout::VL_16B: return ".16b";
|
|
|
|
case AArch64Layout::VL_8H: return ".8h";
|
|
|
|
case AArch64Layout::VL_4S: return ".4s";
|
|
|
|
case AArch64Layout::VL_2D: return ".2d";
|
|
|
|
case AArch64Layout::VL_B: return ".b";
|
|
|
|
case AArch64Layout::VL_H: return ".h";
|
|
|
|
case AArch64Layout::VL_S: return ".s";
|
|
|
|
case AArch64Layout::VL_D: return ".d";
|
2014-04-09 16:42:16 +02:00
|
|
|
default: llvm_unreachable("Unknown Vector Layout");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
inline static AArch64Layout::VectorLayout
|
|
|
|
AArch64StringToVectorLayout(StringRef LayoutStr) {
|
|
|
|
return StringSwitch<AArch64Layout::VectorLayout>(LayoutStr)
|
|
|
|
.Case(".8b", AArch64Layout::VL_8B)
|
|
|
|
.Case(".4h", AArch64Layout::VL_4H)
|
|
|
|
.Case(".2s", AArch64Layout::VL_2S)
|
|
|
|
.Case(".1d", AArch64Layout::VL_1D)
|
|
|
|
.Case(".16b", AArch64Layout::VL_16B)
|
|
|
|
.Case(".8h", AArch64Layout::VL_8H)
|
|
|
|
.Case(".4s", AArch64Layout::VL_4S)
|
|
|
|
.Case(".2d", AArch64Layout::VL_2D)
|
|
|
|
.Case(".b", AArch64Layout::VL_B)
|
|
|
|
.Case(".h", AArch64Layout::VL_H)
|
|
|
|
.Case(".s", AArch64Layout::VL_S)
|
|
|
|
.Case(".d", AArch64Layout::VL_D)
|
|
|
|
.Default(AArch64Layout::Invalid);
|
2014-04-09 16:42:16 +02:00
|
|
|
}
|
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64SysReg {
|
2016-07-05 23:23:04 +02:00
|
|
|
struct SysReg {
|
|
|
|
const char *Name;
|
|
|
|
unsigned Encoding;
|
|
|
|
bool Readable;
|
|
|
|
bool Writeable;
|
|
|
|
FeatureBitset FeaturesRequired;
|
2015-12-01 11:48:51 +01:00
|
|
|
|
2016-07-05 23:23:04 +02:00
|
|
|
bool haveFeatures(FeatureBitset ActiveFeatures) const {
|
|
|
|
return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
|
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
|
|
|
|
2016-07-05 23:23:04 +02:00
|
|
|
#define GET_SYSREG_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2016-07-05 23:23:04 +02:00
|
|
|
const SysReg *lookupSysRegByName(StringRef);
|
|
|
|
const SysReg *lookupSysRegByEncoding(uint16_t);
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2016-07-05 23:23:04 +02:00
|
|
|
uint32_t parseGenericRegister(StringRef Name);
|
|
|
|
std::string genericRegisterString(uint32_t Bits);
|
2015-06-23 11:49:53 +02:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64TLBI {
|
2017-02-27 15:45:34 +01:00
|
|
|
struct TLBI : SysAliasReg {
|
|
|
|
using SysAliasReg::SysAliasReg;
|
2014-04-09 16:42:16 +02:00
|
|
|
};
|
2020-11-12 10:50:58 +01:00
|
|
|
#define GET_TLBITable_DECL
|
2016-07-05 23:23:04 +02:00
|
|
|
#include "AArch64GenSystemOperands.inc"
|
2016-01-06 04:53:36 +01:00
|
|
|
}
|
2014-04-09 16:42:16 +02:00
|
|
|
|
2018-09-27 15:47:40 +02:00
|
|
|
namespace AArch64PRCTX {
|
|
|
|
struct PRCTX : SysAliasReg {
|
|
|
|
using SysAliasReg::SysAliasReg;
|
|
|
|
};
|
|
|
|
#define GET_PRCTX_DECL
|
|
|
|
#include "AArch64GenSystemOperands.inc"
|
|
|
|
}
|
|
|
|
|
2014-05-24 14:50:23 +02:00
|
|
|
namespace AArch64II {
|
2014-03-29 11:18:08 +01:00
|
|
|
/// Target Operand Flag enum.
|
|
|
|
enum TOF {
|
|
|
|
//===------------------------------------------------------------------===//
|
2014-05-24 14:50:23 +02:00
|
|
|
// AArch64 Specific MachineOperand flags.
|
2014-03-29 11:18:08 +01:00
|
|
|
|
|
|
|
MO_NO_FLAG,
|
|
|
|
|
2018-09-04 22:56:21 +02:00
|
|
|
MO_FRAGMENT = 0x7,
|
2014-03-29 11:18:08 +01:00
|
|
|
|
|
|
|
/// MO_PAGE - A symbol operand with this flag represents the pc-relative
|
|
|
|
/// offset of the 4K page containing the symbol. This is used with the
|
|
|
|
/// ADRP instruction.
|
|
|
|
MO_PAGE = 1,
|
|
|
|
|
|
|
|
/// MO_PAGEOFF - A symbol operand with this flag represents the offset of
|
|
|
|
/// that symbol within a 4K page. This offset is added to the page address
|
|
|
|
/// to produce the complete address.
|
|
|
|
MO_PAGEOFF = 2,
|
|
|
|
|
|
|
|
/// MO_G3 - A symbol operand with this flag (granule 3) represents the high
|
|
|
|
/// 16-bits of a 64-bit address, used in a MOVZ or MOVK instruction
|
|
|
|
MO_G3 = 3,
|
|
|
|
|
|
|
|
/// MO_G2 - A symbol operand with this flag (granule 2) represents the bits
|
|
|
|
/// 32-47 of a 64-bit address, used in a MOVZ or MOVK instruction
|
|
|
|
MO_G2 = 4,
|
|
|
|
|
|
|
|
/// MO_G1 - A symbol operand with this flag (granule 1) represents the bits
|
|
|
|
/// 16-31 of a 64-bit address, used in a MOVZ or MOVK instruction
|
|
|
|
MO_G1 = 5,
|
|
|
|
|
|
|
|
/// MO_G0 - A symbol operand with this flag (granule 0) represents the bits
|
|
|
|
/// 0-15 of a 64-bit address, used in a MOVZ or MOVK instruction
|
|
|
|
MO_G0 = 6,
|
|
|
|
|
Fix PR22408 - LLVM producing AArch64 TLS relocations that GNU linkers cannot handle yet.
As is described at http://llvm.org/bugs/show_bug.cgi?id=22408, the GNU linkers
ld.bfd and ld.gold currently only support a subset of the whole range of AArch64
ELF TLS relocations. Furthermore, they assume that some of the code sequences to
access thread-local variables are produced in a very specific sequence.
When the sequence is not as the linker expects, it can silently mis-relaxe/mis-optimize
the instructions.
Even if that wouldn't be the case, it's good to produce the exact sequence,
as that ensures that linkers can perform optimizing relaxations.
This patch:
* implements support for 16MiB TLS area size instead of 4GiB TLS area size. Ideally clang
would grow an -mtls-size option to allow support for both, but that's not part of this patch.
* by default doesn't produce local dynamic access patterns, as even modern ld.bfd and ld.gold
linkers do not support the associated relocations. An option (-aarch64-elf-ldtls-generation)
is added to enable generation of local dynamic code sequence, but is off by default.
* makes sure that the exact expected code sequence for local dynamic and general dynamic
accesses is produced, by making use of a new pseudo instruction. The patch also removes
two (AArch64ISD::TLSDESC_BLR, AArch64ISD::TLSDESC_CALL) pre-existing AArch64-specific pseudo
SDNode instructions that are superseded by the new one (TLSDESC_CALLSEQ).
llvm-svn: 231227
2015-03-04 10:12:08 +01:00
|
|
|
/// MO_HI12 - This flag indicates that a symbol operand represents the bits
|
|
|
|
/// 13-24 of a 64-bit address, used in a arithmetic immediate-shifted-left-
|
|
|
|
/// by-12-bits instruction.
|
|
|
|
MO_HI12 = 7,
|
|
|
|
|
2018-09-04 22:56:21 +02:00
|
|
|
/// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
|
2020-08-04 13:26:16 +02:00
|
|
|
/// reference is actually to the ".refptr.FOO" symbol. This is used for
|
2018-09-04 22:56:21 +02:00
|
|
|
/// stub symbols on windows.
|
|
|
|
MO_COFFSTUB = 0x8,
|
|
|
|
|
2014-03-29 11:18:08 +01:00
|
|
|
/// MO_GOT - This flag indicates that a symbol operand represents the
|
|
|
|
/// address of the GOT entry for the symbol, rather than the address of
|
|
|
|
/// the symbol itself.
|
Fix PR22408 - LLVM producing AArch64 TLS relocations that GNU linkers cannot handle yet.
As is described at http://llvm.org/bugs/show_bug.cgi?id=22408, the GNU linkers
ld.bfd and ld.gold currently only support a subset of the whole range of AArch64
ELF TLS relocations. Furthermore, they assume that some of the code sequences to
access thread-local variables are produced in a very specific sequence.
When the sequence is not as the linker expects, it can silently mis-relaxe/mis-optimize
the instructions.
Even if that wouldn't be the case, it's good to produce the exact sequence,
as that ensures that linkers can perform optimizing relaxations.
This patch:
* implements support for 16MiB TLS area size instead of 4GiB TLS area size. Ideally clang
would grow an -mtls-size option to allow support for both, but that's not part of this patch.
* by default doesn't produce local dynamic access patterns, as even modern ld.bfd and ld.gold
linkers do not support the associated relocations. An option (-aarch64-elf-ldtls-generation)
is added to enable generation of local dynamic code sequence, but is off by default.
* makes sure that the exact expected code sequence for local dynamic and general dynamic
accesses is produced, by making use of a new pseudo instruction. The patch also removes
two (AArch64ISD::TLSDESC_BLR, AArch64ISD::TLSDESC_CALL) pre-existing AArch64-specific pseudo
SDNode instructions that are superseded by the new one (TLSDESC_CALLSEQ).
llvm-svn: 231227
2015-03-04 10:12:08 +01:00
|
|
|
MO_GOT = 0x10,
|
2014-03-29 11:18:08 +01:00
|
|
|
|
|
|
|
/// MO_NC - Indicates whether the linker is expected to check the symbol
|
|
|
|
/// reference for overflow. For example in an ADRP/ADD pair of relocations
|
|
|
|
/// the ADRP usually does check, but not the ADD.
|
Fix PR22408 - LLVM producing AArch64 TLS relocations that GNU linkers cannot handle yet.
As is described at http://llvm.org/bugs/show_bug.cgi?id=22408, the GNU linkers
ld.bfd and ld.gold currently only support a subset of the whole range of AArch64
ELF TLS relocations. Furthermore, they assume that some of the code sequences to
access thread-local variables are produced in a very specific sequence.
When the sequence is not as the linker expects, it can silently mis-relaxe/mis-optimize
the instructions.
Even if that wouldn't be the case, it's good to produce the exact sequence,
as that ensures that linkers can perform optimizing relaxations.
This patch:
* implements support for 16MiB TLS area size instead of 4GiB TLS area size. Ideally clang
would grow an -mtls-size option to allow support for both, but that's not part of this patch.
* by default doesn't produce local dynamic access patterns, as even modern ld.bfd and ld.gold
linkers do not support the associated relocations. An option (-aarch64-elf-ldtls-generation)
is added to enable generation of local dynamic code sequence, but is off by default.
* makes sure that the exact expected code sequence for local dynamic and general dynamic
accesses is produced, by making use of a new pseudo instruction. The patch also removes
two (AArch64ISD::TLSDESC_BLR, AArch64ISD::TLSDESC_CALL) pre-existing AArch64-specific pseudo
SDNode instructions that are superseded by the new one (TLSDESC_CALLSEQ).
llvm-svn: 231227
2015-03-04 10:12:08 +01:00
|
|
|
MO_NC = 0x20,
|
2014-03-29 11:18:08 +01:00
|
|
|
|
|
|
|
/// MO_TLS - Indicates that the operand being accessed is some kind of
|
|
|
|
/// thread-local symbol. On Darwin, only one type of thread-local access
|
|
|
|
/// exists (pre linker-relaxation), but on ELF the TLSModel used for the
|
|
|
|
/// referee will affect interpretation.
|
2017-10-25 09:25:18 +02:00
|
|
|
MO_TLS = 0x40,
|
|
|
|
|
|
|
|
/// MO_DLLIMPORT - On a symbol operand, this represents that the reference
|
|
|
|
/// to the symbol is for an import stub. This is used for DLL import
|
|
|
|
/// storage class indication on Windows.
|
|
|
|
MO_DLLIMPORT = 0x80,
|
2019-01-10 05:59:44 +01:00
|
|
|
|
|
|
|
/// MO_S - Indicates that the bits of the symbol operand represented by
|
|
|
|
/// MO_G0 etc are signed.
|
|
|
|
MO_S = 0x100,
|
2019-07-31 22:14:19 +02:00
|
|
|
|
|
|
|
/// MO_PREL - Indicates that the bits of the symbol operand represented by
|
|
|
|
/// MO_G0 etc are PC relative.
|
|
|
|
MO_PREL = 0x200,
|
|
|
|
|
|
|
|
/// MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag
|
|
|
|
/// in bits 56-63.
|
MemTag: unchecked load/store optimization.
Summary:
MTE allows memory access to bypass tag check iff the address argument
is [SP, #imm]. This change takes advantage of this to demote uses of
tagged addresses to regular FrameIndex operands, reducing register
pressure in large functions.
MO_TAGGED target flag is used to signal that the FrameIndex operand
refers to memory that might be tagged, and needs to be handled with
care. Such operand must be lowered to [SP, #imm] directly, without a
scratch register.
The transformation pass attempts to predict when the offset will be
out of range and disable the optimization.
AArch64RegisterInfo::eliminateFrameIndex has an escape hatch in case
this prediction has been wrong, but it is quite inefficient and should
be avoided.
Reviewers: pcc, vitalybuka, ostannard
Subscribers: mgorny, javed.absar, kristof.beyls, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66457
llvm-svn: 370490
2019-08-30 19:23:02 +02:00
|
|
|
/// On a FrameIndex operand, indicates that the underlying memory is tagged
|
|
|
|
/// with an unknown tag value (MTE); this needs to be lowered either to an
|
|
|
|
/// SP-relative load or store instruction (which do not check tags), or to
|
|
|
|
/// an LDG instruction to obtain the tag value.
|
2019-07-31 22:14:19 +02:00
|
|
|
MO_TAGGED = 0x400,
|
2014-03-29 11:18:08 +01:00
|
|
|
};
|
2014-05-24 14:50:23 +02:00
|
|
|
} // end namespace AArch64II
|
2014-03-29 11:18:08 +01:00
|
|
|
|
[AArch64][SVE] Add intrinsics for gather loads with 64-bit offsets
This patch adds the following intrinsics for gather loads with 64-bit offsets:
* @llvm.aarch64.sve.ld1.gather (unscaled offset)
* @llvm.aarch64.sve.ld1.gather.index (scaled offset)
These intrinsics map 1-1 to the following AArch64 instructions respectively (examples for half-words):
* ld1h { z0.d }, p0/z, [x0, z0.d]
* ld1h { z0.d }, p0/z, [x0, z0.d, lsl #1]
Committing on behalf of Andrzej Warzynski (andwar)
Reviewers: sdesmalen, huntergr, rovka, mgudim, dancgr, rengolin, efriedma
Reviewed By: efriedma
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70542
2019-12-03 12:25:07 +01:00
|
|
|
namespace AArch64 {
|
|
|
|
// The number of bits in a SVE register is architecturally defined
|
|
|
|
// to be a multiple of this value. If <M x t> has this number of bits,
|
|
|
|
// a <n x M x t> vector can be stored in a SVE register without any
|
|
|
|
// redundant bits. If <M x t> has this number of bits divided by P,
|
|
|
|
// a <n x M x t> vector is stored in a SVE register by placing index i
|
|
|
|
// in index i*P of a <n x (M*P) x t> vector. The other elements of the
|
|
|
|
// <n x (M*P) x t> vector (such as index 1) are undefined.
|
|
|
|
static constexpr unsigned SVEBitsPerBlock = 128;
|
2020-01-22 11:42:57 +01:00
|
|
|
static constexpr unsigned SVEMaxBitsPerVector = 2048;
|
2019-12-05 14:07:02 +01:00
|
|
|
const unsigned NeonBitsPerVector = 128;
|
[AArch64][SVE] Add intrinsics for gather loads with 64-bit offsets
This patch adds the following intrinsics for gather loads with 64-bit offsets:
* @llvm.aarch64.sve.ld1.gather (unscaled offset)
* @llvm.aarch64.sve.ld1.gather.index (scaled offset)
These intrinsics map 1-1 to the following AArch64 instructions respectively (examples for half-words):
* ld1h { z0.d }, p0/z, [x0, z0.d]
* ld1h { z0.d }, p0/z, [x0, z0.d, lsl #1]
Committing on behalf of Andrzej Warzynski (andwar)
Reviewers: sdesmalen, huntergr, rovka, mgudim, dancgr, rengolin, efriedma
Reviewed By: efriedma
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70542
2019-12-03 12:25:07 +01:00
|
|
|
} // end namespace AArch64
|
2014-03-29 11:18:08 +01:00
|
|
|
} // end namespace llvm
|
|
|
|
|
|
|
|
#endif
|