diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index db92a94e40e4b..97e92a57a7ff4 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -622,8 +622,13 @@ def FeatureLdpAlignedOnly : SubtargetFeature<"ldp-aligned-only", "HasLdpAlignedO def FeatureStpAlignedOnly : SubtargetFeature<"stp-aligned-only", "HasStpAlignedOnly", "true", "In order to emit stp, first check if the store will be aligned to 2 * element_size">; +// AArch64 2023 Architecture Extensions (v9.5-A) + def FeatureCPA : SubtargetFeature<"cpa", "HasCPA", "true", - "Enable ARMv9.5-A Checked Pointer Arithmetic (FEAT_CPA)">; + "Enable Armv9.5-A Checked Pointer Arithmetic (FEAT_CPA)">; + +def FeaturePAuthLR : SubtargetFeature<"pauth-lr", "HasPAuthLR", + "true", "Enable Armv9.5-A PAC enhancements (FEAT_PAuth_LR)">; //===----------------------------------------------------------------------===// // Architectures. @@ -810,7 +815,7 @@ def SMEUnsupported : AArch64Unsupported { SME2Unsupported.F); } -let F = [HasPAuth] in +let F = [HasPAuth, HasPAuthLR] in def PAUnsupported : AArch64Unsupported; include "AArch64SchedA53.td" diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 690ac0dcda621..cb63d8726744d 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -2368,6 +2368,80 @@ class ClearAuth data, string asm> let Inst{4-0} = Rd; } +// v9.5-A FEAT_PAuth_LR + +class SignAuthFixedRegs opcode2, bits<6> opcode, string asm> + : I<(outs), (ins), asm, "", "", []>, + Sched<[WriteI, ReadI]> { + let Inst{31} = 0b1; // sf + let Inst{30} = 0b1; + let Inst{29} = 0b0; // S + let Inst{28-21} = 0b11010110; + let Inst{20-16} = opcode2; + let Inst{15-10} = opcode; + let Inst{9-5} = 0b11111; // Rn + let Inst{4-0} = 0b11110; // Rd +} + +def PAuthPCRelLabel16Operand : PCRelLabel<16> { + let Name = "PAuthPCRelLabel16"; + let PredicateMethod = "isPAuthPCRelLabel16Operand"; +} +def am_pauth_pcrel : Operand { + let EncoderMethod = "getPAuthPCRelOpValue"; + let DecoderMethod = "DecodePCRelLabel16"; + let PrintMethod = "printAlignedLabel"; + let ParserMatchClass = PAuthPCRelLabel16Operand; + let OperandType = "OPERAND_PCREL"; +} + +class SignAuthPCRel opc, string asm> + : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>, + Sched<[]> { + bits<16> label; + let Inst{31} = 0b1; // sf + let Inst{30-23} = 0b11100111; + let Inst{22-21} = opc; + let Inst{20-5} = label; // imm + let Inst{4-0} = 0b11111; // Rd +} + +class SignAuthOneReg opcode2, bits<6> opcode, string asm> + : I<(outs), (ins GPR64:$Rn), asm, "\t$Rn", "", []>, + Sched<[]> { + bits<5> Rn; + let Inst{31} = 0b1; // sf + let Inst{30} = 0b1; + let Inst{29} = 0b0; // S + let Inst{28-21} = 0b11010110; + let Inst{20-16} = opcode2; + let Inst{15-10} = opcode; + let Inst{9-5} = Rn; + let Inst{4-0} = 0b11110; // Rd +} + +class SignAuthReturnPCRel opc, bits<5> op2, string asm> + : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>, + Sched<[WriteAtomic]> { + bits<16> label; + let Inst{31-24} = 0b01010101; + let Inst{23-21} = opc; + let Inst{20-5} = label; // imm16 + let Inst{4-0} = op2; +} + +class SignAuthReturnReg op3, string asm> + : I<(outs), (ins GPR64common:$Rm), asm, "\t$Rm", "", []>, + Sched<[WriteAtomic]> { + bits<5> Rm; + let Inst{31-25} = 0b1101011; + let Inst{24-21} = 0b0010; // opc + let Inst{20-16} = 0b11111; // op2 + let Inst{15-10} = op3; + let Inst{9-5} = 0b11111; // Rn + let Inst{4-0} = Rm; // op4 (Rm) +} + // Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions class BaseFlagManipulation : I<(outs), iops, asm, ops, "", []>, diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 4ccac40f99a0a..977729bb082b7 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -61,6 +61,9 @@ def HasLOR : Predicate<"Subtarget->hasLOR()">, def HasPAuth : Predicate<"Subtarget->hasPAuth()">, AssemblerPredicateWithAll<(all_of FeaturePAuth), "pauth">; +def HasPAuthLR : Predicate<"Subtarget->hasPAuthLR()">, + AssemblerPredicateWithAll<(all_of FeaturePAuthLR), "pauth-lr">; + def HasJS : Predicate<"Subtarget->hasJS()">, AssemblerPredicateWithAll<(all_of FeatureJS), "jsconv">; @@ -1646,6 +1649,42 @@ let Predicates = [HasPAuth] in { } +// v9.5-A pointer authentication extensions + +// Always accept "pacm" as an alias for "hint #39", but don't emit it when +// disassembling if we don't have the pauth-lr feature. +let CRm = 0b0100 in { + def PACM : SystemNoOperands<0b111, "hint\t#39">; +} +def : InstAlias<"pacm", (PACM), 0>; + +let Predicates = [HasPAuthLR] in { + let Defs = [LR], Uses = [LR, SP] in { + // opcode2, opcode, asm + def PACIASPPC : SignAuthFixedRegs<0b00001, 0b101000, "paciasppc">; + def PACIBSPPC : SignAuthFixedRegs<0b00001, 0b101001, "pacibsppc">; + def PACNBIASPPC : SignAuthFixedRegs<0b00001, 0b100000, "pacnbiasppc">; + def PACNBIBSPPC : SignAuthFixedRegs<0b00001, 0b100001, "pacnbibsppc">; + // opc, asm + def AUTIASPPCi : SignAuthPCRel<0b00, "autiasppc">; + def AUTIBSPPCi : SignAuthPCRel<0b01, "autibsppc">; + // opcode2, opcode, asm + def AUTIASPPCr : SignAuthOneReg<0b00001, 0b100100, "autiasppc">; + def AUTIBSPPCr : SignAuthOneReg<0b00001, 0b100101, "autibsppc">; + } + + let Uses = [LR, SP], isReturn = 1, isTerminator = 1, isBarrier = 1 in { + // opc, op2, asm + def RETAASPPCi : SignAuthReturnPCRel<0b000, 0b11111, "retaasppc">; + def RETABSPPCi : SignAuthReturnPCRel<0b001, 0b11111, "retabsppc">; + // op3, asm + def RETAASPPCr : SignAuthReturnReg<0b000010, "retaasppc">; + def RETABSPPCr : SignAuthReturnReg<0b000011, "retabsppc">; + } + def : InstAlias<"pacm", (PACM), 1>; +} + + // v8.3a floating point conversion for javascript let Predicates = [HasJS, HasFPARMv8], Defs = [NZCV] in def FJCVTZS : BaseFPToIntegerUnscaled<0b01, 0b11, 0b110, FPR64, GPR32, diff --git a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td index 813b4a3affcfd..7edce4b61605d 100644 --- a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td +++ b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td @@ -22,7 +22,7 @@ def A64FXModel : SchedMachineModel { list UnsupportedFeatures = !listconcat(SMEUnsupported.F, SVEUnsupported.F, [HasMTE, HasMatMulInt8, HasBF16, - HasPAuth, HasCPA]); + HasPAuth, HasPAuthLR, HasCPA]); let FullInstRWOverlapCheck = 0; } diff --git a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td index 53cf725f0e235..a6fab5e6245f8 100644 --- a/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td +++ b/llvm/lib/Target/AArch64/AArch64SchedNeoverseN2.td @@ -19,7 +19,7 @@ def NeoverseN2Model : SchedMachineModel { let CompleteModel = 1; list UnsupportedFeatures = !listconcat(SMEUnsupported.F, - [HasSVE2p1, HasCPA]); + [HasSVE2p1, HasPAuthLR, HasCPA]); } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 74afa4183e67e..38a92cb096029 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1696,6 +1696,21 @@ class AArch64Operand : public MCParsedAsmOperand { return DiagnosticPredicateTy::Match; } + bool isPAuthPCRelLabel16Operand() const { + // PAuth PCRel16 operands are similar to regular branch targets, but only + // negative values are allowed for concrete immediates as signing instr + // should be in a lower address. + if (!isImm()) + return false; + const MCConstantExpr *MCE = dyn_cast(getImm()); + if (!MCE) + return true; + int64_t Val = MCE->getValue(); + if (Val & 0b11) + return false; + return (Val <= 0) && (Val > -(1 << 18)); + } + void addExpr(MCInst &Inst, const MCExpr *Expr) const { // Add as immediates when possible. Null MCExpr = 0. if (!Expr) @@ -1997,6 +2012,19 @@ class AArch64Operand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); } + void addPAuthPCRelLabel16Operands(MCInst &Inst, unsigned N) const { + // PC-relative operands don't encode the low bits, so shift them off + // here. If it's a label, however, just put it on directly as there's + // not enough information now to do anything. + assert(N == 1 && "Invalid number of operands!"); + const MCConstantExpr *MCE = dyn_cast(getImm()); + if (!MCE) { + addExpr(Inst, getImm()); + return; + } + Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2)); + } + void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const { // Branch operands don't encode the low bits, so shift them off // here. If it's a label, however, just put it on directly as there's diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index cf2d3879292d1..e3220d103ae0d 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -165,6 +165,9 @@ static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm, static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm, uint64_t Address, const MCDisassembler *Decoder); +static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm, + uint64_t Address, + const MCDisassembler *Decoder); static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm, uint64_t Address, const MCDisassembler *Decoder); @@ -887,6 +890,21 @@ static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm, return Success; } +static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm, + uint64_t Addr, + const MCDisassembler *Decoder) { + // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative + // PC-relative offset. + uint64_t ImmVal = Imm; + if (ImmVal < 0 || ImmVal > (1 << 16)) + return Fail; + ImmVal = -ImmVal; + if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr, + /*IsBranch=*/false, 0, 0, 4)) + Inst.addOperand(MCOperand::createImm(ImmVal)); + return Success; +} + static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index a6900b8963bb3..30ef3680ae79c 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -67,6 +67,7 @@ class AArch64AsmBackend : public MCAsmBackend { {"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal}, {"fixup_aarch64_movw", 5, 16, 0}, {"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal}, + {"fixup_aarch64_pcrel_branch16", 5, 16, PCRelFlagVal}, {"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal}, {"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal}, {"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal}}; @@ -121,6 +122,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { case AArch64::fixup_aarch64_movw: case AArch64::fixup_aarch64_pcrel_branch14: + case AArch64::fixup_aarch64_pcrel_branch16: case AArch64::fixup_aarch64_add_imm12: case AArch64::fixup_aarch64_ldst_imm12_scale1: case AArch64::fixup_aarch64_ldst_imm12_scale2: @@ -314,6 +316,17 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, if (Value & 0x3) Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned"); return (Value >> 2) & 0x3fff; + case AArch64::fixup_aarch64_pcrel_branch16: + // Unsigned PC-relative offset, so invert the negative immediate. + SignedValue = -SignedValue; + Value = static_cast(SignedValue); + // Check valid 18-bit unsigned range. + if (SignedValue < 0 || SignedValue > ((1 << 18) - 1)) + Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); + // Low two bits are not encoded (4-byte alignment assumed). + if (Value & 0b11) + Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned"); + return (Value >> 2) & 0xffff; case AArch64::fixup_aarch64_pcrel_branch26: case AArch64::fixup_aarch64_pcrel_call26: if (TheTriple.isOSBinFormatCOFF() && !IsResolved && SignedValue != 0) { @@ -380,6 +393,7 @@ unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) con case AArch64::fixup_aarch64_movw: case AArch64::fixup_aarch64_pcrel_branch14: + case AArch64::fixup_aarch64_pcrel_branch16: case AArch64::fixup_aarch64_add_imm12: case AArch64::fixup_aarch64_ldst_imm12_scale1: case AArch64::fixup_aarch64_ldst_imm12_scale2: diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp index 9de40661298cc..496ab18e9b195 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -186,6 +186,10 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, return R_CLS(LD_PREL_LO19); case AArch64::fixup_aarch64_pcrel_branch14: return R_CLS(TSTBR14); + case AArch64::fixup_aarch64_pcrel_branch16: + Ctx.reportError(Fixup.getLoc(), + "relocation of PAC/AUT instructions is not supported"); + return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_pcrel_branch19: return R_CLS(CONDBR19); default: diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h index 767dd88055201..fdee2d5ad2bf3 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h @@ -43,6 +43,11 @@ enum Fixups { // The high 14 bits of a 21-bit pc-relative immediate. fixup_aarch64_pcrel_branch14, + // The high 16 bits of a 18-bit unsigned PC-relative immediate. Used by + // pointer authentication, only within a function, so no relocation can be + // generated. + fixup_aarch64_pcrel_branch16, + // The high 19 bits of a 21-bit pc-relative immediate. Same encoding as // fixup_aarch64_pcrel_adrhi, except this is use by b.cc and generates // relocations directly when necessary. diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp index dbc4323a860f5..c3e12b6d8024e 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp @@ -88,6 +88,12 @@ class AArch64MCCodeEmitter : public MCCodeEmitter { SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + /// getPAuthPCRelOpValue - Return the encoded value for a pointer + /// authentication pc-relative operand. + uint32_t getPAuthPCRelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + /// getLoadLiteralOpValue - Return the encoded value for a load-literal /// pc-relative address. uint32_t getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx, @@ -327,6 +333,29 @@ uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue( return 0; } +/// getPAuthPCRelOpValue - Return the encoded value for a pointer +/// authentication pc-relative operand. +uint32_t +AArch64MCCodeEmitter::getPAuthPCRelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpIdx); + + // If the destination is an immediate, invert sign as it's a negative value + // that should be encoded as unsigned + if (MO.isImm()) + return -(MO.getImm()); + assert(MO.isExpr() && "Unexpected target type!"); + + MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch16); + Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); + + ++MCNumFixups; + + // All of the information is in the fixup. + return 0; +} + /// getLoadLiteralOpValue - Return the encoded value for a load-literal /// pc-relative address. uint32_t diff --git a/llvm/test/MC/AArch64/armv9.5a-pauthlr-diagnostics.s b/llvm/test/MC/AArch64/armv9.5a-pauthlr-diagnostics.s new file mode 100644 index 0000000000000..d06183be9da3e --- /dev/null +++ b/llvm/test/MC/AArch64/armv9.5a-pauthlr-diagnostics.s @@ -0,0 +1,57 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+pauth-lr 2>&1 < %s | FileCheck %s + + autiasppc #2 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: autiasppc #2 +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + autiasppc #1<<17 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: autiasppc #1<<17 +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + autiasppc #-2 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: autiasppc #-2 +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + autiasppc w0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: autiasppc w0 +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + autiasppc sp +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: autiasppc sp +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + retabsppc #2 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: retabsppc #2 +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + retabsppc #(1<<17) +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: retabsppc #(1<<17) +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + retabsppc #-2 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: retabsppc #-2 +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + retaasppc w0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: retaasppc w0 +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + retaasppc sp +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: retaasppc sp +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + retaasppc xzr +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected label or encodable integer pc offset +// CHECK-NEXT: retaasppc xzr +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + diff --git a/llvm/test/MC/AArch64/armv9.5a-pauthlr-reloc.s b/llvm/test/MC/AArch64/armv9.5a-pauthlr-reloc.s new file mode 100644 index 0000000000000..c10142a199766 --- /dev/null +++ b/llvm/test/MC/AArch64/armv9.5a-pauthlr-reloc.s @@ -0,0 +1,12 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+pauth-lr -filetype=obj -o /dev/null 2>&1 < %s | FileCheck %s + + autiasppc undef_label +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: relocation of PAC/AUT instructions is not supported +// CHECK-NEXT: autiasppc undef_label +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + + autibsppc undef_label +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: relocation of PAC/AUT instructions is not supported +// CHECK-NEXT: autibsppc undef_label +// CHECK-NOT: [[@LINE-3]]:{{[0-9]+}}: + diff --git a/llvm/test/MC/AArch64/armv9.5a-pauthlr.s b/llvm/test/MC/AArch64/armv9.5a-pauthlr.s new file mode 100644 index 0000000000000..24e9c44984683 --- /dev/null +++ b/llvm/test/MC/AArch64/armv9.5a-pauthlr.s @@ -0,0 +1,151 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+pauth-lr < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+pauth-lr < %s \ +// RUN: | llvm-objdump -d --mattr=+pauth-lr - | FileCheck %s --check-prefix=CHECK-DISASS +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+pauth-lr < %s \ +// RUN: | llvm-objdump -d --mattr=-pauth-lr - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +// Label at address 4, so we can test that the address shows up in the +// disassembly. + nop +label1: + + paciasppc +// CHECK-INST: paciasppc +// CHECK-DISASS: paciasppc +// CHECK-ENCODING: [0xfe,0xa3,0xc1,0xda] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: dac1a3fe + + pacibsppc +// CHECK-INST: pacibsppc +// CHECK-DISASS: pacibsppc +// CHECK-ENCODING: [0xfe,0xa7,0xc1,0xda] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: dac1a7fe + + pacnbiasppc +// CHECK-INST: pacnbiasppc +// CHECK-DISASS: pacnbiasppc +// CHECK-ENCODING: [0xfe,0x83,0xc1,0xda] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: dac183fe + + pacnbibsppc +// CHECK-INST: pacnbibsppc +// CHECK-DISASS: pacnbibsppc +// CHECK-ENCODING: [0xfe,0x87,0xc1,0xda] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: dac187fe + + autiasppc label1 +// CHECK-INST: autiasppc label1 +// CHECK-DISASS: autiasppc 0x4 +// CHECK-ENCODING: [0bAAA11111,A,0b100AAAAA,0xf3] +// CHECK-ENCODING: fixup A - offset: 0, value: label1, kind: fixup_aarch64_pcrel_branch16 +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: f380009f + + autibsppc label1 +// CHECK-INST: autibsppc label1 +// CHECK-DISASS: autibsppc 0x4 +// CHECK-ENCODING: [0bAAA11111,A,0b101AAAAA,0xf3] +// CHECK-ENCODING: fixup A - offset: 0, value: label1, kind: fixup_aarch64_pcrel_branch16 +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: f3a000bf + + autibsppc #0 +// CHECK-INST: autibsppc #0 +// CHECK-DISASS: autibsppc 0x1c +// CHECK-ENCODING: [0x1f,0x00,0xa0,0xf3] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: f3a0001f + + autibsppc #-(1<<18)+4 +// CHECK-INST: autibsppc #-262140 +// CHECK-DISASS: autibsppc 0xfffffffffffc0024 +// CHECK-ENCODING: [0xff,0xff,0xbf,0xf3] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: f3bfffff + + autiasppc x0 +// CHECK-INST: autiasppc x0 +// CHECK-DISASS: autiasppc x0 +// CHECK-ENCODING: [0x1e,0x90,0xc1,0xda] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: dac1901e + + autibsppc x1 +// CHECK-INST: autibsppc x1 +// CHECK-DISASS: autibsppc x1 +// CHECK-ENCODING: [0x3e,0x94,0xc1,0xda] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: dac1943e + + autiasppc xzr +// CHECK-INST: autiasppc xzr +// CHECK-DISASS: autiasppc xzr +// CHECK-ENCODING: [0xfe,0x93,0xc1,0xda] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: dac193fe + + autibsppc xzr +// CHECK-INST: autibsppc xzr +// CHECK-DISASS: autibsppc xzr +// CHECK-ENCODING: [0xfe,0x97,0xc1,0xda] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: dac197fe + + + retaasppc label1 +// CHECK-INST: retaasppc label1 +// CHECK-DISASS: retaasppc 0x4 +// CHECK-ENCODING: [0bAAA11111,A,0b000AAAAA,0x55] +// CHECK-ENCODING: // fixup A - offset: 0, value: label1, kind: fixup_aarch64_pcrel_branch16 +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: 5500019f + + retabsppc label1 +// CHECK-INST: retabsppc label1 +// CHECK-DISASS: retabsppc 0x4 +// CHECK-ENCODING: [0bAAA11111,A,0b001AAAAA,0x55] +// CHECK-ENCODING: // fixup A - offset: 0, value: label1, kind: fixup_aarch64_pcrel_branch16 +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: 552001bf + + retaasppc #0 +// CHECK-INST: retaasppc #0 +// CHECK-DISASS: retaasppc 0x3c +// CHECK-ENCODING: [0x1f,0x00,0x00,0x55] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: 5500001f + + retaasppc #-(1<<18)+4 +// CHECK-INST: retaasppc #-262140 +// CHECK-DISASS: retaasppc 0xfffffffffffc0044 +// CHECK-ENCODING: [0xff,0xff,0x1f,0x55] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: 551fffff + + retaasppc x2 +// CHECK-INST: retaasppc x2 +// CHECK-DISASS: retaasppc x2 +// CHECK-ENCODING: [0xe2,0x0b,0x5f,0xd6] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: d65f0be2 + + retabsppc x3 +// CHECK-INST: retabsppc x3 +// CHECK-DISASS: retabsppc x3 +// CHECK-ENCODING: [0xe3,0x0f,0x5f,0xd6] +// CHECK-ERROR: instruction requires: pauth-lr +// CHECK-UNKNOWN: d65f0fe3 + + pacm +// CHECK-INST: pacm +// CHECK-DISASS: pacm +// CHECK-ENCODING: [0xff,0x24,0x03,0xd5] +// CHECK-ERROR-NOT: instruction requires: +// CHECK-UNKNOWN: d50324ff hint #39 diff --git a/llvm/test/MC/Disassembler/AArch64/armv9.5a-pauthlr.txt b/llvm/test/MC/Disassembler/AArch64/armv9.5a-pauthlr.txt new file mode 100644 index 0000000000000..caf1fde2c2b7c --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv9.5a-pauthlr.txt @@ -0,0 +1,78 @@ +# RUN: llvm-mc -triple aarch64 -disassemble -mattr=+pauth-lr < %s | FileCheck %s +# RUN: not llvm-mc -triple aarch64 -disassemble < %s 2>&1 | FileCheck %s --check-prefix=NO-PAUTHLR + +[0xfe,0xa3,0xc1,0xda] +# CHECK: paciasppc +# NO-PAUTHLR: invalid instruction encoding + +[0xfe,0xa7,0xc1,0xda] +# CHECK: pacibsppc +# NO-PAUTHLR: invalid instruction encoding + +[0xfe,0x83,0xc1,0xda] +# CHECK: pacnbiasppc +# NO-PAUTHLR: invalid instruction encoding + +[0xfe,0x87,0xc1,0xda] +# CHECK: pacnbibsppc +# NO-PAUTHLR: invalid instruction encoding + +[0x9f,0x00,0x80,0xf3] +# CHECK: autiasppc #-16 +# NO-PAUTHLR: invalid instruction encoding + +[0xbf,0x00,0xa0,0xf3] +# CHECK: autibsppc #-20 +# NO-PAUTHLR: invalid instruction encoding + +[0x1f,0x00,0xa0,0xf3] +# CHECK: autibsppc #0 +# NO-PAUTHLR: invalid instruction encoding + +[0xff,0xff,0xbf,0xf3] +# CHECK: autibsppc #-262140 +# NO-PAUTHLR: invalid instruction encoding + +[0x1e,0x90,0xc1,0xda] +# CHECK: autiasppc x0 +# NO-PAUTHLR: invalid instruction encoding + +[0x3e,0x94,0xc1,0xda] +# CHECK: autibsppc x1 +# NO-PAUTHLR: invalid instruction encoding + +[0xfe,0x93,0xc1,0xda] +# CHECK: autiasppc xzr +# NO-PAUTHLR: invalid instruction encoding + +[0xfe,0x97,0xc1,0xda] +# CHECK: autibsppc xzr +# NO-PAUTHLR: invalid instruction encoding + +[0xbf,0x01,0x00,0x55] +# CHECK: retaasppc #-52 +# NO-PAUTHLR: invalid instruction encoding + +[0xdf,0x01,0x20,0x55] +# CHECK: retabsppc #-56 +# NO-PAUTHLR: invalid instruction encoding + +[0x1f,0x00,0x00,0x55] +# CHECK: retaasppc #0 +# NO-PAUTHLR: invalid instruction encoding + +[0xff,0xff,0x1f,0x55] +# CHECK: retaasppc #-262140 +# NO-PAUTHLR: invalid instruction encoding + +[0xe2,0x0b,0x5f,0xd6] +# CHECK: retaasppc x2 +# NO-PAUTHLR: invalid instruction encoding + +[0xe3,0x0f,0x5f,0xd6] +# CHECK: retabsppc x3 +# NO-PAUTHLR: invalid instruction encoding + +[0xff,0x24,0x03,0xd5] +# CHECK: pacm +# NO-PAUTHLR: hint #39