1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[AArch64] Enable ARMv8.3-A pointer authentication

Add assembler and disassembler support for the ARMv8.3-A pointer
authentication instructions.

Differential Revision: https://reviews.llvm.org/D36517

llvm-svn: 310709
This commit is contained in:
Sam Parker 2017-08-11 13:14:00 +00:00
parent f4051e8c3e
commit ea4cb0a3a7
11 changed files with 663 additions and 7 deletions

View File

@ -189,6 +189,11 @@ def GPR32as64 : RegisterOperand<GPR32> {
// are encoded as the eight bit value 'abcdefgh'.
def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
def SImm10s8Operand : AsmOperandClass {
let Name = "SImm10s8";
let DiagnosticType = "InvalidMemoryIndexedSImm10";
}
//===----------------------------------------------------------------------===//
// Operand Definitions.
@ -216,6 +221,12 @@ def adrlabel : Operand<i64> {
let ParserMatchClass = AdrOperand;
}
def simm10Scaled : Operand<i64> {
let ParserMatchClass = SImm10s8Operand;
let DecoderMethod = "DecodeSImm<10>";
let PrintMethod = "printImmScale<8>";
}
// simm9 predicate - True if the immediate is in the range [-256, 255].
def SImm9Operand : AsmOperandClass {
let Name = "SImm9";
@ -913,6 +924,17 @@ class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
let Inst{7-5} = opc;
}
class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
: SimpleSystemI<0, (ins), asm, "", pattern>,
Sched<[]> {
bits<4> CRm;
let CRm = 0b0011;
let Inst{31-12} = 0b11010101000000110010;
let Inst{11-8} = CRm;
let Inst{7-5} = op2;
let Inst{4-0} = 0b11111;
}
// MRS/MSR system instructions. These have different operand classes because
// a different subset of registers can be accessed through each instruction.
def MRSSystemRegisterOperand : AsmOperandClass {
@ -1110,6 +1132,72 @@ class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
let Inst{4-0} = Rt;
}
class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
list<dag> pattern>
: I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
let Inst{31-25} = 0b1101011;
let Inst{20-11} = 0b1111100001;
let Inst{10} = M;
let Inst{4-0} = 0b11111;
}
class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
: AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
bits<5> Rn;
bits<5> Rm;
let Inst{24-22} = 0b100;
let Inst{21} = op;
let Inst{9-5} = Rn;
let Inst{4-0} = Rm;
}
class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
: AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
bits<5> Rn;
let Inst{24} = 0;
let Inst{23-21} = opc;
let Inst{9-5} = Rn;
}
class AuthReturn<bits<3> op, bits<1> M, string asm>
: AuthBase<M, (outs), (ins), asm, "", []> {
let Inst{24} = 0;
let Inst{23-21} = op;
let Inst{9-0} = 0b1111111111;
}
let mayLoad = 1 in
class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
string operands, string cstr, Operand opr>
: I<oops, iops, asm, operands, "", []>, Sched<[]> {
bits<10> offset;
bits<5> Rn;
bits<5> Rt;
let Inst{31-24} = 0b11111000;
let Inst{23} = M;
let Inst{22} = offset{9};
let Inst{21} = 1;
let Inst{20-12} = offset{8-0};
let Inst{11} = W;
let Inst{10} = 1;
let Inst{9-5} = Rn;
let Inst{4-0} = Rt;
}
multiclass AuthLoad<bit M, string asm, Operand opr> {
def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), (ins GPR64sp:$Rn, opr:$offset),
asm, "\t$Rt, [$Rn, $offset]", "", opr>;
def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
(ins GPR64sp:$Rn, opr:$offset),
asm, "\t$Rt, [$Rn, $offset]!",
"$Rn = $wback,@earlyclobber $wback", opr> {
let DecoderMethod = "DecodeAuthLoadWriteback";
}
def : InstAlias<asm # "\t$Rt, [$Rn]",
(!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
}
//---
// Conditional branch instruction.
//---
@ -1332,6 +1420,46 @@ class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
let Inst{31} = 1;
}
class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
: I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "",
[]>,
Sched<[WriteI, ReadI]> {
bits<5> Rd;
bits<5> Rn;
let Inst{31-15} = 0b11011010110000010;
let Inst{14-12} = opcode_prefix;
let Inst{11-10} = opcode;
let Inst{9-5} = Rn;
let Inst{4-0} = Rd;
}
class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
: I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> {
bits<5> Rd;
let Inst{31-15} = 0b11011010110000010;
let Inst{14-12} = opcode_prefix;
let Inst{11-10} = opcode;
let Inst{9-5} = 0b11111;
let Inst{4-0} = Rd;
}
class SignAuthTwoOperand<bits<4> opc, string asm,
SDPatternOperator OpNode>
: I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
asm, "\t$Rd, $Rn, $Rm", "",
[(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
Sched<[WriteI, ReadI, ReadI]> {
bits<5> Rd;
bits<5> Rn;
bits<5> Rm;
let Inst{31-21} = 0b10011010110;
let Inst{20-16} = Rm;
let Inst{15-14} = 0b00;
let Inst{13-10} = opc;
let Inst{9-5} = Rn;
let Inst{4-0} = Rd;
}
//---
// Basic two-operand data processing instructions.
//---

View File

@ -458,6 +458,72 @@ let Predicates = [HasRCPC] in {
def LDAPRX : RCPCLoad<0b11, "ldapr", GPR64>;
}
let Predicates = [HasV8_3a] in {
// v8.3a Pointer Authentication
let Uses = [LR], Defs = [LR] in {
def PACIAZ : SystemNoOperands<0b000, "paciaz">;
def PACIBZ : SystemNoOperands<0b010, "pacibz">;
def AUTIAZ : SystemNoOperands<0b100, "autiaz">;
def AUTIBZ : SystemNoOperands<0b110, "autibz">;
}
let Uses = [LR, SP], Defs = [LR] in {
def PACIASP : SystemNoOperands<0b001, "paciasp">;
def PACIBSP : SystemNoOperands<0b011, "pacibsp">;
def AUTIASP : SystemNoOperands<0b101, "autiasp">;
def AUTIBSP : SystemNoOperands<0b111, "autibsp">;
}
let Uses = [X16, X17], Defs = [X17], CRm = 0b0001 in {
def PACIA1716 : SystemNoOperands<0b000, "pacia1716">;
def PACIB1716 : SystemNoOperands<0b010, "pacib1716">;
def AUTIA1716 : SystemNoOperands<0b100, "autia1716">;
def AUTIB1716 : SystemNoOperands<0b110, "autib1716">;
}
let Uses = [LR], Defs = [LR], CRm = 0b0000 in {
def XPACLRI : SystemNoOperands<0b111, "xpaclri">;
}
multiclass SignAuth<bits<3> prefix, bits<3> prefix_z, string asm> {
def IA : SignAuthOneData<prefix, 0b00, !strconcat(asm, "ia")>;
def IB : SignAuthOneData<prefix, 0b01, !strconcat(asm, "ib")>;
def DA : SignAuthOneData<prefix, 0b10, !strconcat(asm, "da")>;
def DB : SignAuthOneData<prefix, 0b11, !strconcat(asm, "db")>;
def IZA : SignAuthZero<prefix_z, 0b00, !strconcat(asm, "iza")>;
def DZA : SignAuthZero<prefix_z, 0b10, !strconcat(asm, "dza")>;
def IZB : SignAuthZero<prefix_z, 0b01, !strconcat(asm, "izb")>;
def DZB : SignAuthZero<prefix_z, 0b11, !strconcat(asm, "dzb")>;
}
defm PAC : SignAuth<0b000, 0b010, "pac">;
defm AUT : SignAuth<0b001, 0b011, "aut">;
def XPACI : SignAuthZero<0b100, 0b00, "xpaci">;
def XPACD : SignAuthZero<0b100, 0b01, "xpacd">;
def PACGA : SignAuthTwoOperand<0b1100, "pacga", null_frag>;
// Combined Instructions
def BRAA : AuthBranchTwoOperands<0, 0, "braa">;
def BRAB : AuthBranchTwoOperands<0, 1, "brab">;
def BLRAA : AuthBranchTwoOperands<1, 0, "blraa">;
def BLRAB : AuthBranchTwoOperands<1, 1, "blrab">;
def BRAAZ : AuthOneOperand<0b000, 0, "braaz">;
def BRABZ : AuthOneOperand<0b000, 1, "brabz">;
def BLRAAZ : AuthOneOperand<0b001, 0, "blraaz">;
def BLRABZ : AuthOneOperand<0b001, 1, "blrabz">;
let isReturn = 1 in {
def RETAA : AuthReturn<0b010, 0, "retaa">;
def RETAB : AuthReturn<0b010, 1, "retab">;
def ERETAA : AuthReturn<0b100, 0, "eretaa">;
def ERETAB : AuthReturn<0b100, 1, "eretab">;
}
defm LDRAA : AuthLoad<0, "ldraa", simm10Scaled>;
defm LDRAB : AuthLoad<1, "ldrab", simm10Scaled>;
} // HasV8_3A
def : InstAlias<"clrex", (CLREX 0xf)>;
def : InstAlias<"isb", (ISB 0xf)>;

View File

@ -239,20 +239,20 @@ def : ReadAdvance<ReadID, 1, [WriteImm, WriteI,
//---
// Branch
//---
def : InstRW<[THXT8XWriteBR], (instregex "^B")>;
def : InstRW<[THXT8XWriteBR], (instregex "^BL")>;
def : InstRW<[THXT8XWriteBR], (instregex "^B.*")>;
def : InstRW<[THXT8XWriteBR], (instregex "^B$")>;
def : InstRW<[THXT8XWriteBR], (instregex "^BL$")>;
def : InstRW<[THXT8XWriteBR], (instregex "^B..$")>;
def : InstRW<[THXT8XWriteBR], (instregex "^CBNZ")>;
def : InstRW<[THXT8XWriteBR], (instregex "^CBZ")>;
def : InstRW<[THXT8XWriteBR], (instregex "^TBNZ")>;
def : InstRW<[THXT8XWriteBR], (instregex "^TBZ")>;
def : InstRW<[THXT8XWriteBRR], (instregex "^BR")>;
def : InstRW<[THXT8XWriteBRR], (instregex "^BLR")>;
def : InstRW<[THXT8XWriteBRR], (instregex "^BR$")>;
def : InstRW<[THXT8XWriteBRR], (instregex "^BLR$")>;
//---
// Ret
//---
def : InstRW<[THXT8XWriteRET], (instregex "^RET")>;
def : InstRW<[THXT8XWriteRET], (instregex "^RET$")>;
//---
// Miscellaneous

View File

@ -398,7 +398,7 @@ def : WriteRes<WriteAtomic, []> {
//---
def : InstRW<[THX2T99Write_1Cyc_I2], (instrs B, BL, BR, BLR)>;
def : InstRW<[THX2T99Write_1Cyc_I2], (instrs RET)>;
def : InstRW<[THX2T99Write_1Cyc_I2], (instregex "^B.*")>;
def : InstRW<[THX2T99Write_1Cyc_I2], (instregex "^B..$")>;
def : InstRW<[THX2T99Write_1Cyc_I2],
(instregex "^CBZ", "^CBNZ", "^TBZ", "^TBNZ")>;

View File

@ -1016,6 +1016,21 @@ def : RWSysReg<"VDISR_EL2", 0b11, 0b100, 0b1100, 0b0001, 0b001>;
def : RWSysReg<"VSESR_EL2", 0b11, 0b100, 0b0101, 0b0010, 0b011>;
}
// v8.3a "Pointer authentication extension" registers
// Op0 Op1 CRn CRm Op2
let Requires = [{ {AArch64::HasV8_3aOps} }] in {
def : RWSysReg<"APIAKeyLo_EL1", 0b11, 0b000, 0b0010, 0b0001, 0b000>;
def : RWSysReg<"APIAKeyHi_EL1", 0b11, 0b000, 0b0010, 0b0001, 0b001>;
def : RWSysReg<"APIBKeyLo_EL1", 0b11, 0b000, 0b0010, 0b0001, 0b010>;
def : RWSysReg<"APIBKeyHi_EL1", 0b11, 0b000, 0b0010, 0b0001, 0b011>;
def : RWSysReg<"APDAKeyLo_EL1", 0b11, 0b000, 0b0010, 0b0010, 0b000>;
def : RWSysReg<"APDAKeyHi_EL1", 0b11, 0b000, 0b0010, 0b0010, 0b001>;
def : RWSysReg<"APDBKeyLo_EL1", 0b11, 0b000, 0b0010, 0b0010, 0b010>;
def : RWSysReg<"APDBKeyHi_EL1", 0b11, 0b000, 0b0010, 0b0010, 0b011>;
def : RWSysReg<"APGAKeyLo_EL1", 0b11, 0b000, 0b0010, 0b0011, 0b000>;
def : RWSysReg<"APGAKeyHi_EL1", 0b11, 0b000, 0b0010, 0b0011, 0b001>;
}
// Cyclone specific system registers
// Op0 Op1 CRn CRm Op2
let Requires = [{ {AArch64::ProcCyclone} }] in

View File

@ -465,6 +465,15 @@ public:
int64_t Val = MCE->getValue();
return (Val >= -256 && Val < 256);
}
bool isSImm10s8() const {
if (!isImm())
return false;
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
return false;
int64_t Val = MCE->getValue();
return (Val >= -4096 && Val < 4089 && (Val & 7) == 0);
}
bool isSImm7s4() const {
if (!isImm())
return false;
@ -1213,6 +1222,12 @@ public:
Inst.addOperand(MCOperand::createImm(MCE->getValue()));
}
void addSImm10s8Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
Inst.addOperand(MCOperand::createImm(MCE->getValue() / 8));
}
void addSImm7s4Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
@ -3299,6 +3314,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
"expected compatible register or floating-point constant");
case Match_InvalidMemoryIndexedSImm9:
return Error(Loc, "index must be an integer in range [-256, 255].");
case Match_InvalidMemoryIndexedSImm10:
return Error(Loc, "index must be a multiple of 8 in range [-4096, 4088].");
case Match_InvalidMemoryIndexed4SImm7:
return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
case Match_InvalidMemoryIndexed8SImm7:
@ -3766,6 +3783,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidMemoryIndexed8SImm7:
case Match_InvalidMemoryIndexed16SImm7:
case Match_InvalidMemoryIndexedSImm9:
case Match_InvalidMemoryIndexedSImm10:
case Match_InvalidImm0_1:
case Match_InvalidImm0_7:
case Match_InvalidImm0_15:

View File

@ -179,6 +179,12 @@ static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Addr,
const void *Decoder);
template<int Bits>
static DecodeStatus DecodeSImm(llvm::MCInst &Inst, uint64_t Imm,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeAuthLoadWriteback(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address,
const void *Decoder);
static bool Check(DecodeStatus &Out, DecodeStatus In) {
switch (In) {
@ -1588,3 +1594,39 @@ static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst &Inst,
AArch64::XSeqPairsClassRegClassID,
RegNo, Addr, Decoder);
}
template<int Bits>
static DecodeStatus DecodeSImm(llvm::MCInst &Inst, uint64_t Imm,
uint64_t Address, const void *Decoder) {
if (Imm & ~((1LL << Bits) - 1))
return Fail;
// Imm is a signed immediate, so sign extend it.
if (Imm & (1 << (Bits - 1)))
Imm |= ~((1LL << Bits) - 1);
Inst.addOperand(MCOperand::createImm(Imm));
return Success;
}
static DecodeStatus DecodeAuthLoadWriteback(llvm::MCInst &Inst, uint32_t insn,
uint64_t Address,
const void *Decoder) {
unsigned Rt = fieldFromInstruction(insn, 0, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
unsigned Imm9 = fieldFromInstruction(insn, 12, 9);
unsigned S = fieldFromInstruction(insn, 22, 1);
unsigned Imm = Imm9 | (S << 9);
// Address writeback
DecodeGPR64spRegisterClass(Inst, Rn, Address, Decoder);
// Destination
DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
// Address
DecodeGPR64spRegisterClass(Inst, Rn, Address, Decoder);
// Offset
DecodeSImm<10>(Inst, Imm, Address, Decoder);
return Success;
}

View File

@ -84,6 +84,12 @@ public:
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// getAuthSImmOpValue - Return encoding for a 10-bit immediate which is
/// encoded as a sign bit and an 9-bit immediate, separated by a single bit.
uint32_t getAuthSImmOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// getCondBranchTargetOpValue - Return the encoded value for a conditional
/// branch target.
uint32_t getCondBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
@ -282,6 +288,18 @@ AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
return ShiftVal == 0 ? 0 : (1 << ShiftVal);
}
/// getAuthSImmOpValue - encode a 10-bit scale signed immediate within an 11-bit
/// field in which bit 10 of that field is not used to encode any information
/// about the immediate.
uint32_t
AArch64MCCodeEmitter::getAuthSImmOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
int32_t offset = MO.getImm();
return (uint32_t)offset;
}
/// getCondBranchTargetOpValue - Return the encoded value for a conditional
/// branch target.
uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(

View File

@ -0,0 +1,20 @@
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.3a < %s 2> %t
// RUN: FileCheck %s < %t
msr ID_ISAR6_EL1, x0
// CHECK: error: expected writable system register or pstate
// CHECK-NEXT: msr ID_ISAR6_EL1, x0
// CHECK-NEXT: ^
ldraa x0, [x1, 4089]
// CHECK: error: index must be a multiple of 8 in range [-4096, 4088].
ldraa x0, [x1, -4097]
// CHECK: error: index must be a multiple of 8 in range [-4096, 4088].
ldraa x0, [x1, 4086]
// CHECK: error: index must be a multiple of 8 in range [-4096, 4088].
ldrab x0, [x1, 4089]
// CHECK: error: index must be a multiple of 8 in range [-4096, 4088].
ldrab x0, [x1, -4097]
// CHECK: error: index must be a multiple of 8 in range [-4096, 4088].
ldrab x0, [x1, 4086]
// CHECK: error: index must be a multiple of 8 in range [-4096, 4088].

View File

@ -0,0 +1,235 @@
// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.3a < %s 2> %t | FileCheck %s
// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2> %t
// RUN: FileCheck --check-prefix=CHECK-REQ %s < %t
mrs x0, apiakeylo_el1
mrs x0, apiakeyhi_el1
mrs x0, apibkeylo_el1
mrs x0, apibkeyhi_el1
mrs x0, apdakeylo_el1
mrs x0, apdakeyhi_el1
mrs x0, apdbkeylo_el1
mrs x0, apdbkeyhi_el1
mrs x0, apgakeylo_el1
mrs x0, apgakeyhi_el1
// CHECK: mrs x0, APIAKeyLo_EL1 // encoding: [0x00,0x21,0x38,0xd5]
// CHECK: mrs x0, APIAKeyHi_EL1 // encoding: [0x20,0x21,0x38,0xd5]
// CHECK: mrs x0, APIBKeyLo_EL1 // encoding: [0x40,0x21,0x38,0xd5]
// CHECK: mrs x0, APIBKeyHi_EL1 // encoding: [0x60,0x21,0x38,0xd5]
// CHECK: mrs x0, APDAKeyLo_EL1 // encoding: [0x00,0x22,0x38,0xd5]
// CHECK: mrs x0, APDAKeyHi_EL1 // encoding: [0x20,0x22,0x38,0xd5]
// CHECK: mrs x0, APDBKeyLo_EL1 // encoding: [0x40,0x22,0x38,0xd5]
// CHECK: mrs x0, APDBKeyHi_EL1 // encoding: [0x60,0x22,0x38,0xd5]
// CHECK: mrs x0, APGAKeyLo_EL1 // encoding: [0x00,0x23,0x38,0xd5]
// CHECK: mrs x0, APGAKeyHi_EL1 // encoding: [0x20,0x23,0x38,0xd5]
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
// CHECK-REQ: error: expected readable system register
msr apiakeylo_el1, x0
msr apiakeyhi_el1, x0
msr apibkeylo_el1, x0
msr apibkeyhi_el1, x0
msr apdakeylo_el1, x0
msr apdakeyhi_el1, x0
msr apdbkeylo_el1, x0
msr apdbkeyhi_el1, x0
msr apgakeylo_el1, x0
msr apgakeyhi_el1, x0
// CHECK: msr APIAKeyLo_EL1, x0 // encoding: [0x00,0x21,0x18,0xd5]
// CHECK: msr APIAKeyHi_EL1, x0 // encoding: [0x20,0x21,0x18,0xd5]
// CHECK: msr APIBKeyLo_EL1, x0 // encoding: [0x40,0x21,0x18,0xd5]
// CHECK: msr APIBKeyHi_EL1, x0 // encoding: [0x60,0x21,0x18,0xd5]
// CHECK: msr APDAKeyLo_EL1, x0 // encoding: [0x00,0x22,0x18,0xd5]
// CHECK: msr APDAKeyHi_EL1, x0 // encoding: [0x20,0x22,0x18,0xd5]
// CHECK: msr APDBKeyLo_EL1, x0 // encoding: [0x40,0x22,0x18,0xd5]
// CHECK: msr APDBKeyHi_EL1, x0 // encoding: [0x60,0x22,0x18,0xd5]
// CHECK: msr APGAKeyLo_EL1, x0 // encoding: [0x00,0x23,0x18,0xd5]
// CHECK: msr APGAKeyHi_EL1, x0 // encoding: [0x20,0x23,0x18,0xd5]
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
// CHECK-REQ: error: expected writable system register or pstate
paciasp
// CHECK: paciasp // encoding: [0x3f,0x23,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
autiasp
// CHECK: autiasp // encoding: [0xbf,0x23,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
paciaz
// CHECK: paciaz // encoding: [0x1f,0x23,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
autiaz
// CHECK: autiaz // encoding: [0x9f,0x23,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
pacia1716
// CHECK: pacia1716 // encoding: [0x1f,0x21,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
autia1716
// CHECK: autia1716 // encoding: [0x9f,0x21,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
pacibsp
// CHECK: pacibsp // encoding: [0x7f,0x23,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
autibsp
// CHECK: autibsp // encoding: [0xff,0x23,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
pacibz
// CHECK: pacibz // encoding: [0x5f,0x23,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
autibz
// CHECK: autibz // encoding: [0xdf,0x23,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
pacib1716
// CHECK: pacib1716 // encoding: [0x5f,0x21,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
autib1716
// CHECK: autib1716 // encoding: [0xdf,0x21,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
xpaclri
// CHECK: xpaclri // encoding: [0xff,0x20,0x03,0xd5]
// CHECK-REQ: error: instruction requires: armv8.3a
pacia x0, x1
// CHECK: pacia x0, x1 // encoding: [0x20,0x00,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
autia x0, x1
// CHECK: autia x0, x1 // encoding: [0x20,0x10,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
pacda x0, x1
// CHECK: pacda x0, x1 // encoding: [0x20,0x08,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
autda x0, x1
// CHECK: autda x0, x1 // encoding: [0x20,0x18,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
pacib x0, x1
// CHECK: pacib x0, x1 // encoding: [0x20,0x04,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
autib x0, x1
// CHECK: autib x0, x1 // encoding: [0x20,0x14,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
pacdb x0, x1
// CHECK: pacdb x0, x1 // encoding: [0x20,0x0c,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
autdb x0, x1
// CHECK: autdb x0, x1 // encoding: [0x20,0x1c,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
pacga x0, x1, x2
// CHECK: pacga x0, x1, x2 // encoding: [0x20,0x30,0xc2,0x9a]
// CHECK-REQ: error: instruction requires: armv8.3a
paciza x0
// CHECK: paciza x0 // encoding: [0xe0,0x23,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
autiza x0
// CHECK: autiza x0 // encoding: [0xe0,0x33,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
pacdza x0
// CHECK: pacdza x0 // encoding: [0xe0,0x2b,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
autdza x0
// CHECK: autdza x0 // encoding: [0xe0,0x3b,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
pacizb x0
// CHECK: pacizb x0 // encoding: [0xe0,0x27,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
autizb x0
// CHECK: autizb x0 // encoding: [0xe0,0x37,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
pacdzb x0
// CHECK: pacdzb x0 // encoding: [0xe0,0x2f,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
autdzb x0
// CHECK: autdzb x0 // encoding: [0xe0,0x3f,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
xpaci x0
// CHECK: xpaci x0 // encoding: [0xe0,0x43,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
xpacd x0
// CHECK: xpacd x0 // encoding: [0xe0,0x47,0xc1,0xda]
// CHECK-REQ: error: instruction requires: armv8.3a
braa x0, x1
// CHECK: braa x0, x1 // encoding: [0x01,0x08,0x1f,0xd7]
// CHECK-REQ: error: instruction requires: armv8.3a
brab x0, x1
// CHECK: brab x0, x1 // encoding: [0x01,0x0c,0x1f,0xd7]
// CHECK-REQ: error: instruction requires: armv8.3a
blraa x0, x1
// CHECK: blraa x0, x1 // encoding: [0x01,0x08,0x3f,0xd7]
// CHECK-REQ: error: instruction requires: armv8.3a
blrab x0, x1
// CHECK: blrab x0, x1 // encoding: [0x01,0x0c,0x3f,0xd7]
// CHECK-REQ: error: instruction requires: armv8.3a
braaz x0
// CHECK: braaz x0 // encoding: [0x1f,0x08,0x1f,0xd6]
// CHECK-REQ: error: instruction requires: armv8.3a
brabz x0
// CHECK: brabz x0 // encoding: [0x1f,0x0c,0x1f,0xd6]
// CHECK-REQ: error: instruction requires: armv8.3a
blraaz x0
// CHECK: blraaz x0 // encoding: [0x1f,0x08,0x3f,0xd6]
// CHECK-REQ: error: instruction requires: armv8.3a
blrabz x0
// CHECK: blrabz x0 // encoding: [0x1f,0x0c,0x3f,0xd6]
// CHECK-REQ: error: instruction requires: armv8.3a
retaa
// CHECK: retaa // encoding: [0xff,0x0b,0x5f,0xd6]
// CHECK-REQ: error: instruction requires: armv8.3a
retab
// CHECK: retab // encoding: [0xff,0x0f,0x5f,0xd6]
// CHECK-REQ: error: instruction requires: armv8.3a
eretaa
// CHECK: eretaa // encoding: [0xff,0x0b,0x9f,0xd6]
// CHECK-REQ: error: instruction requires: armv8.3a
eretab
// CHECK: eretab // encoding: [0xff,0x0f,0x9f,0xd6]
// CHECK-REQ: error: instruction requires: armv8.3a
ldraa x0, [x1, 4088]
// CHECK: ldraa x0, [x1, #4088] // encoding: [0x20,0xf4,0x3f,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldraa x0, [x1, -4096]
// CHECK: ldraa x0, [x1, #-4096] // encoding: [0x20,0x04,0x60,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldrab x0, [x1, 4088]
// CHECK: ldrab x0, [x1, #4088] // encoding: [0x20,0xf4,0xbf,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldrab x0, [x1, -4096]
// CHECK: ldrab x0, [x1, #-4096] // encoding: [0x20,0x04,0xe0,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldraa x0, [x1, 4088]!
// CHECK: ldraa x0, [x1, #4088]! // encoding: [0x20,0xfc,0x3f,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldraa x0, [x1, -4096]!
// CHECK: ldraa x0, [x1, #-4096]! // encoding: [0x20,0x0c,0x60,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldrab x0, [x1, 4088]!
// CHECK: ldrab x0, [x1, #4088]! // encoding: [0x20,0xfc,0xbf,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldrab x0, [x1, -4096]!
// CHECK: ldrab x0, [x1, #-4096]! // encoding: [0x20,0x0c,0xe0,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldraa x0, [x1]
// CHECK: ldraa x0, [x1] // encoding: [0x20,0x04,0x20,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a
ldrab x0, [x1]
// CHECK: ldrab x0, [x1] // encoding: [0x20,0x04,0xa0,0xf8]
// CHECK-REQ: error: instruction requires: armv8.3a

View File

@ -0,0 +1,114 @@
# RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.3a --disassemble < %s | FileCheck %s
# CHECK: paciasp
# CHECK: autiasp
# CHECK: paciaz
# CHECK: autiaz
# CHECK: pacia1716
# CHECK: autia1716
# CHECK: pacibsp
# CHECK: autibsp
# CHECK: pacibz
# CHECK: autibz
# CHECK: pacib1716
# CHECK: autib1716
# CHECK: xpaclri
[0x3f,0x23,0x03,0xd5]
[0xbf,0x23,0x03,0xd5]
[0x1f,0x23,0x03,0xd5]
[0x9f,0x23,0x03,0xd5]
[0x1f,0x21,0x03,0xd5]
[0x9f,0x21,0x03,0xd5]
[0x7f,0x23,0x03,0xd5]
[0xff,0x23,0x03,0xd5]
[0x5f,0x23,0x03,0xd5]
[0xdf,0x23,0x03,0xd5]
[0x5f,0x21,0x03,0xd5]
[0xdf,0x21,0x03,0xd5]
[0xff,0x20,0x03,0xd5]
# CHECK: pacia x0, x1
# CHECK: autia x0, x1
# CHECK: pacda x0, x1
# CHECK: autda x0, x1
# CHECK: pacib x0, x1
# CHECK: autib x0, x1
# CHECK: pacdb x0, x1
# CHECK: autdb x0, x1
# CHECK: pacga x0, x1, x2
# CHECK: paciza x0
# CHECK: autiza x0
# CHECK: pacdza x0
# CHECK: autdza x0
# CHECK: pacizb x0
# CHECK: autizb x0
# CHECK: pacdzb x0
# CHECK: autdzb x0
# CHECK: xpaci x0
# CHECK: xpacd x0
[0x20,0x00,0xc1,0xda]
[0x20,0x10,0xc1,0xda]
[0x20,0x08,0xc1,0xda]
[0x20,0x18,0xc1,0xda]
[0x20,0x04,0xc1,0xda]
[0x20,0x14,0xc1,0xda]
[0x20,0x0c,0xc1,0xda]
[0x20,0x1c,0xc1,0xda]
[0x20,0x30,0xc2,0x9a]
[0xe0,0x23,0xc1,0xda]
[0xe0,0x33,0xc1,0xda]
[0xe0,0x2b,0xc1,0xda]
[0xe0,0x3b,0xc1,0xda]
[0xe0,0x27,0xc1,0xda]
[0xe0,0x37,0xc1,0xda]
[0xe0,0x2f,0xc1,0xda]
[0xe0,0x3f,0xc1,0xda]
[0xe0,0x43,0xc1,0xda]
[0xe0,0x47,0xc1,0xda]
# CHECK: braa x0, x1
# CHECK: brab x0, x1
# CHECK: blraa x0, x1
# CHECK: blrab x0, x1
[0x01,0x08,0x1f,0xd7]
[0x01,0x0c,0x1f,0xd7]
[0x01,0x08,0x3f,0xd7]
[0x01,0x0c,0x3f,0xd7]
# CHECK: braaz x0
# CHECK: brabz x0
# CHECK: blraaz x0
# CHECK: blrabz x0
# CHECK: retaa
# CHECK: retab
# CHECK: eretaa
# CHECK: eretab
# CHECK: ldraa x0, [x1, #4088]
# CHECK: ldraa x0, [x1, #-4096]
# CHECK: ldrab x0, [x1, #4088]
# CHECK: ldrab x0, [x1, #-4096]
# CHECK: ldraa x0, [x1, #4088]!
# CHECK: ldraa x0, [x1, #-4096]!
# CHECK: ldrab x0, [x1, #4088]!
# CHECK: ldrab x0, [x1, #-4096]!
[0x1f,0x08,0x1f,0xd6]
[0x1f,0x0c,0x1f,0xd6]
[0x1f,0x08,0x3f,0xd6]
[0x1f,0x0c,0x3f,0xd6]
[0xff,0x0b,0x5f,0xd6]
[0xff,0x0f,0x5f,0xd6]
[0xff,0x0b,0x9f,0xd6]
[0xff,0x0f,0x9f,0xd6]
[0x20,0xf4,0x3f,0xf8]
[0x20,0x04,0x60,0xf8]
[0x20,0xf4,0xbf,0xf8]
[0x20,0x04,0xe0,0xf8]
[0x20,0xfc,0x3f,0xf8]
[0x20,0x0c,0x60,0xf8]
[0x20,0xfc,0xbf,0xf8]
[0x20,0x0c,0xe0,0xf8]
# CHECK: ldraa x0, [x1]
# CHECK: ldrab x0, [x1]
[0x20,0x04,0x20,0xf8]
[0x20,0x04,0xa0,0xf8]