From ce8e2a0d91724b07d3a262c6005e5705a3b7837e Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Tue, 1 Dec 2015 10:48:51 +0000 Subject: [PATCH] [AArch64] Add ARMv8.2-A Statistical Profiling Extension The Statistical Profiling Extension is an optional extension to ARMv8.2-A. Since it is an optional extension, I have added the FeatureSPE subtarget feature to control it. The assembler-visible parts of this extension are the new "psb csync" instruction, which is equivalent to "hint #17", and a number of system registers. Differential Revision: http://reviews.llvm.org/D15021 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254401 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64.td | 3 + lib/Target/AArch64/AArch64InstrFormats.td | 19 ++++ lib/Target/AArch64/AArch64InstrInfo.td | 5 + lib/Target/AArch64/AArch64Subtarget.h | 2 + .../AArch64/AsmParser/AArch64AsmParser.cpp | 73 ++++++++++++++- .../InstPrinter/AArch64InstPrinter.cpp | 13 +++ .../AArch64/InstPrinter/AArch64InstPrinter.h | 3 + lib/Target/AArch64/Utils/AArch64BaseInfo.cpp | 23 +++++ lib/Target/AArch64/Utils/AArch64BaseInfo.h | 30 ++++++ .../AArch64/armv8.2a-statistical-profiling.s | 87 ++++++++++++++++++ .../armv8.2a-statistical-profiling.txt | 91 +++++++++++++++++++ utils/TableGen/AsmWriterEmitter.cpp | 12 ++- 12 files changed, 355 insertions(+), 6 deletions(-) create mode 100644 test/MC/AArch64/armv8.2a-statistical-profiling.s create mode 100644 test/MC/Disassembler/AArch64/armv8.2a-statistical-profiling.txt diff --git a/lib/Target/AArch64/AArch64.td b/lib/Target/AArch64/AArch64.td index e82cdd00ba1..5c19b3efdb1 100644 --- a/lib/Target/AArch64/AArch64.td +++ b/lib/Target/AArch64/AArch64.td @@ -38,6 +38,9 @@ def FeaturePerfMon : SubtargetFeature<"perfmon", "HasPerfMon", "true", def FeatureFullFP16 : SubtargetFeature<"fullfp16", "HasFullFP16", "true", "Full FP16", [FeatureFPARMv8]>; +def FeatureSPE : SubtargetFeature<"spe", "HasSPE", "true", + "Enable Statistical Profiling extension">; + /// Cyclone has register move instructions which are "free". def FeatureZCRegMove : SubtargetFeature<"zcm", "HasZeroCycleRegMove", "true", "Has zero-cycle register moves">; diff --git a/lib/Target/AArch64/AArch64InstrFormats.td b/lib/Target/AArch64/AArch64InstrFormats.td index 752a153c057..5eef82153e3 100644 --- a/lib/Target/AArch64/AArch64InstrFormats.td +++ b/lib/Target/AArch64/AArch64InstrFormats.td @@ -911,6 +911,25 @@ def msr_sysreg_op : Operand { let PrintMethod = "printMSRSystemRegister"; } +def PSBHintOperand : AsmOperandClass { + let Name = "PSBHint"; + let ParserMethod = "tryParsePSBHint"; +} +def psbhint_op : Operand { + let ParserMatchClass = PSBHintOperand; + let PrintMethod = "printPSBHintOp"; + let MCOperandPredicate = [{ + // Check, if operand is valid, to fix exhaustive aliasing in disassembly. + // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. + if (!MCOp.isImm()) + return false; + bool ValidNamed; + (void)AArch64PSBHint::PSBHintMapper().toString(MCOp.getImm(), + STI.getFeatureBits(), ValidNamed); + return ValidNamed; + }]; +} + class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), "mrs", "\t$Rt, $systemreg"> { bits<16> systemreg; diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td index 0c43003975c..881f55ebeef 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.td +++ b/lib/Target/AArch64/AArch64InstrInfo.td @@ -29,6 +29,8 @@ def HasCRC : Predicate<"Subtarget->hasCRC()">, def HasPerfMon : Predicate<"Subtarget->hasPerfMon()">; def HasFullFP16 : Predicate<"Subtarget->hasFullFP16()">, AssemblerPredicate<"FeatureFullFP16", "fullfp16">; +def HasSPE : Predicate<"Subtarget->hasSPE()">, + AssemblerPredicate<"FeatureSPE", "spe">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; @@ -382,6 +384,9 @@ def : InstAlias<"wfi", (HINT 0b011)>; def : InstAlias<"sev", (HINT 0b100)>; def : InstAlias<"sevl", (HINT 0b101)>; +// v8.2a Statistical Profiling extension +def : InstAlias<"psb $op", (HINT psbhint_op:$op)>, Requires<[HasSPE]>; + // As far as LLVM is concerned this writes to the system's exclusive monitors. let mayLoad = 1, mayStore = 1 in def CLREX : CRmSystemI; diff --git a/lib/Target/AArch64/AArch64Subtarget.h b/lib/Target/AArch64/AArch64Subtarget.h index 9aa6ef9ab67..73daf6051b7 100644 --- a/lib/Target/AArch64/AArch64Subtarget.h +++ b/lib/Target/AArch64/AArch64Subtarget.h @@ -47,6 +47,7 @@ protected: bool HasCRC; bool HasPerfMon; bool HasFullFP16; + bool HasSPE; // HasZeroCycleRegMove - Has zero-cycle register mov instructions. bool HasZeroCycleRegMove; @@ -124,6 +125,7 @@ public: bool hasPerfMon() const { return HasPerfMon; } bool hasFullFP16() const { return HasFullFP16; } + bool hasSPE() const { return HasSPE; } bool isLittleEndian() const { return IsLittle; } diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 165843fc84c..f0ad855ed5e 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -100,6 +100,7 @@ private: OperandMatchResultTy tryParseSysReg(OperandVector &Operands); OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands); OperandMatchResultTy tryParsePrefetch(OperandVector &Operands); + OperandMatchResultTy tryParsePSBHint(OperandVector &Operands); OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands); OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands); OperandMatchResultTy tryParseFPImm(OperandVector &Operands); @@ -159,7 +160,8 @@ private: k_Prefetch, k_ShiftExtend, k_FPImm, - k_Barrier + k_Barrier, + k_PSBHint, } Kind; SMLoc StartLoc, EndLoc; @@ -227,6 +229,12 @@ private: unsigned Length; }; + struct PSBHintOp { + unsigned Val; + const char *Data; + unsigned Length; + }; + struct ShiftExtendOp { AArch64_AM::ShiftExtendType Type; unsigned Amount; @@ -250,6 +258,7 @@ private: struct SysRegOp SysReg; struct SysCRImmOp SysCRImm; struct PrefetchOp Prefetch; + struct PSBHintOp PSBHint; struct ShiftExtendOp ShiftExtend; }; @@ -301,6 +310,9 @@ public: case k_Prefetch: Prefetch = o.Prefetch; break; + case k_PSBHint: + PSBHint = o.PSBHint; + break; case k_ShiftExtend: ShiftExtend = o.ShiftExtend; break; @@ -392,6 +404,16 @@ public: return Prefetch.Val; } + unsigned getPSBHint() const { + assert(Kind == k_PSBHint && "Invalid access!"); + return PSBHint.Val; + } + + StringRef getPSBHintName() const { + assert(Kind == k_PSBHint && "Invalid access!"); + return StringRef(PSBHint.Data, PSBHint.Length); + } + StringRef getPrefetchName() const { assert(Kind == k_Prefetch && "Invalid access!"); return StringRef(Prefetch.Data, Prefetch.Length); @@ -961,6 +983,7 @@ public: } bool isSysCR() const { return Kind == k_SysCR; } bool isPrefetch() const { return Kind == k_Prefetch; } + bool isPSBHint() const { return Kind == k_PSBHint; } bool isShiftExtend() const { return Kind == k_ShiftExtend; } bool isShifter() const { if (!isShiftExtend()) @@ -1534,6 +1557,11 @@ public: Inst.addOperand(MCOperand::createImm(getPrefetch())); } + void addPSBHintOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createImm(getPSBHint())); + } + void addShifterOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); unsigned Imm = @@ -1730,6 +1758,19 @@ public: return Op; } + static std::unique_ptr CreatePSBHint(unsigned Val, + StringRef Str, + SMLoc S, + MCContext &Ctx) { + auto Op = make_unique(k_PSBHint, Ctx); + Op->PSBHint.Val = Val; + Op->PSBHint.Data = Str.data(); + Op->PSBHint.Length = Str.size(); + Op->StartLoc = S; + Op->EndLoc = S; + return Op; + } + static std::unique_ptr CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val, bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) { @@ -1803,6 +1844,10 @@ void AArch64Operand::print(raw_ostream &OS) const { OS << ""; break; } + case k_PSBHint: { + OS << getPSBHintName(); + break; + } case k_ShiftExtend: { OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #" << getShiftExtendAmount(); @@ -2069,6 +2114,32 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { return MatchOperand_Success; } +/// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command +AArch64AsmParser::OperandMatchResultTy +AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + SMLoc S = getLoc(); + const AsmToken &Tok = Parser.getTok(); + if (Tok.isNot(AsmToken::Identifier)) { + TokError("invalid operand for instruction"); + return MatchOperand_ParseFail; + } + + bool Valid; + auto Mapper = AArch64PSBHint::PSBHintMapper(); + unsigned psbhint = + Mapper.fromString(Tok.getString(), getSTI().getFeatureBits(), Valid); + if (!Valid) { + TokError("invalid operand for instruction"); + return MatchOperand_ParseFail; + } + + Parser.Lex(); // Eat identifier token. + Operands.push_back(AArch64Operand::CreatePSBHint(psbhint, Tok.getString(), + S, getContext())); + return MatchOperand_Success; +} + /// tryParseAdrpLabel - Parse and validate a source label for the ADRP /// instruction. AArch64AsmParser::OperandMatchResultTy diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp index d8937b57e49..480ed0d263a 100644 --- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1144,6 +1144,19 @@ void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum, O << '#' << prfop; } +void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + unsigned psbhintop = MI->getOperand(OpNum).getImm(); + bool Valid; + StringRef Name = + AArch64PSBHint::PSBHintMapper().toString(psbhintop, STI.getFeatureBits(), Valid); + if (Valid) + O << Name; + else + O << '#' << psbhintop; +} + void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h index a94721816d3..a767aa451c6 100644 --- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -123,6 +123,9 @@ protected: void printPrefetchOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + void printPSBHintOp(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + void printFPImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); diff --git a/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp index f657eaab815..78f5289ec26 100644 --- a/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ b/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -154,6 +154,14 @@ const AArch64NamedImmMapper::Mapping AArch64PState::PStateMapper::PStateMappings AArch64PState::PStateMapper::PStateMapper() : AArch64NamedImmMapper(PStateMappings, 0) {} +const AArch64NamedImmMapper::Mapping AArch64PSBHint::PSBHintMapper::PSBHintMappings[] = { + // v8.2a "Statistical Profiling" extension-specific PSB operand + {"csync", CSync, {AArch64::FeatureSPE}}, +}; + +AArch64PSBHint::PSBHintMapper::PSBHintMapper() + : AArch64NamedImmMapper(PSBHintMappings, 0) {} + const AArch64NamedImmMapper::Mapping AArch64SysReg::MRSMapper::MRSMappings[] = { {"mdccsr_el0", MDCCSR_EL0, {}}, {"dbgdtrrx_el0", DBGDTRRX_EL0, {}}, @@ -808,6 +816,21 @@ const AArch64NamedImmMapper::Mapping AArch64SysReg::SysRegMapper::SysRegMappings // v8.2a registers {"uao", UAO, {AArch64::HasV8_2aOps}}, + + // v8.2a "Statistical Profiling extension" registers + {"pmblimitr_el1", PMBLIMITR_EL1, {AArch64::FeatureSPE}}, + {"pmbptr_el1", PMBPTR_EL1, {AArch64::FeatureSPE}}, + {"pmbsr_el1", PMBSR_EL1, {AArch64::FeatureSPE}}, + {"pmbidr_el1", PMBIDR_EL1, {AArch64::FeatureSPE}}, + {"pmscr_el2", PMSCR_EL2, {AArch64::FeatureSPE}}, + {"pmscr_el12", PMSCR_EL12, {AArch64::FeatureSPE}}, + {"pmscr_el1", PMSCR_EL1, {AArch64::FeatureSPE}}, + {"pmsicr_el1", PMSICR_EL1, {AArch64::FeatureSPE}}, + {"pmsirr_el1", PMSIRR_EL1, {AArch64::FeatureSPE}}, + {"pmsfcr_el1", PMSFCR_EL1, {AArch64::FeatureSPE}}, + {"pmsevfr_el1", PMSEVFR_EL1, {AArch64::FeatureSPE}}, + {"pmslatfr_el1", PMSLATFR_EL1, {AArch64::FeatureSPE}}, + {"pmsidr_el1", PMSIDR_EL1, {AArch64::FeatureSPE}}, }; uint32_t diff --git a/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/lib/Target/AArch64/Utils/AArch64BaseInfo.h index 5a6b54bbee8..f649cb9b8a8 100644 --- a/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -478,6 +478,21 @@ namespace AArch64PState { } +namespace AArch64PSBHint { + enum PSBHintValues { + Invalid = -1, + // v8.2a "Statistical Profiling" extension-specific PSB operands + CSync = 0x11, // psb csync = hint #0x11 + }; + + struct PSBHintMapper : AArch64NamedImmMapper { + const static Mapping PSBHintMappings[]; + + PSBHintMapper(); + }; + +} + namespace AArch64SE { enum ShiftExtSpecifiers { Invalid = -1, @@ -1199,6 +1214,21 @@ namespace AArch64SysReg { // v8.2a registers UAO = 0xc214, // 11 000 0100 0010 100 + // v8.2a "Statistical Profiling extension" registers + PMBLIMITR_EL1 = 0xc4d0, // 11 000 1001 1010 000 + PMBPTR_EL1 = 0xc4d1, // 11 000 1001 1010 001 + PMBSR_EL1 = 0xc4d3, // 11 000 1001 1010 011 + PMBIDR_EL1 = 0xc4d7, // 11 000 1001 1010 111 + PMSCR_EL2 = 0xe4c8, // 11 100 1001 1001 000 + PMSCR_EL12 = 0xecc8, // 11 101 1001 1001 000 + PMSCR_EL1 = 0xc4c8, // 11 000 1001 1001 000 + PMSICR_EL1 = 0xc4ca, // 11 000 1001 1001 010 + PMSIRR_EL1 = 0xc4cb, // 11 000 1001 1001 011 + PMSFCR_EL1 = 0xc4cc, // 11 000 1001 1001 100 + PMSEVFR_EL1 = 0xc4cd, // 11 000 1001 1001 101 + PMSLATFR_EL1 = 0xc4ce, // 11 000 1001 1001 110 + PMSIDR_EL1 = 0xc4cf, // 11 000 1001 1001 111 + // Cyclone specific system registers CPM_IOACC_CTL_EL3 = 0xff90, }; diff --git a/test/MC/AArch64/armv8.2a-statistical-profiling.s b/test/MC/AArch64/armv8.2a-statistical-profiling.s new file mode 100644 index 00000000000..5cb10931878 --- /dev/null +++ b/test/MC/AArch64/armv8.2a-statistical-profiling.s @@ -0,0 +1,87 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+spe < %s | FileCheck %s +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding < %s 2>&1 | FileCheck --check-prefix=NO_SPE %s + + psb csync +// CHECK: psb csync // encoding: [0x3f,0x22,0x03,0xd5] +// NO_SPE: invalid operand for instruction + + msr pmblimitr_el1, x0 + msr pmbptr_el1, x0 + msr pmbsr_el1, x0 + msr pmbidr_el1, x0 + msr pmscr_el2, x0 + msr pmscr_el12, x0 + msr pmscr_el1, x0 + msr pmsicr_el1, x0 + msr pmsirr_el1, x0 + msr pmsfcr_el1, x0 + msr pmsevfr_el1, x0 + msr pmslatfr_el1, x0 + msr pmsidr_el1, x0 +// CHECK: msr PMBLIMITR_EL1, x0 // encoding: [0x00,0x9a,0x18,0xd5] +// CHECK: msr PMBPTR_EL1, x0 // encoding: [0x20,0x9a,0x18,0xd5] +// CHECK: msr PMBSR_EL1, x0 // encoding: [0x60,0x9a,0x18,0xd5] +// CHECK: msr PMBIDR_EL1, x0 // encoding: [0xe0,0x9a,0x18,0xd5] +// CHECK: msr PMSCR_EL2, x0 // encoding: [0x00,0x99,0x1c,0xd5] +// CHECK: msr PMSCR_EL12, x0 // encoding: [0x00,0x99,0x1d,0xd5] +// CHECK: msr PMSCR_EL1, x0 // encoding: [0x00,0x99,0x18,0xd5] +// CHECK: msr PMSICR_EL1, x0 // encoding: [0x40,0x99,0x18,0xd5] +// CHECK: msr PMSIRR_EL1, x0 // encoding: [0x60,0x99,0x18,0xd5] +// CHECK: msr PMSFCR_EL1, x0 // encoding: [0x80,0x99,0x18,0xd5] +// CHECK: msr PMSEVFR_EL1, x0 // encoding: [0xa0,0x99,0x18,0xd5] +// CHECK: msr PMSLATFR_EL1, x0 // encoding: [0xc0,0x99,0x18,0xd5] +// CHECK: msr PMSIDR_EL1, x0 // encoding: [0xe0,0x99,0x18,0xd5] +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate +// NO_SPE: error: expected writable system register or pstate + +mrs x0, pmblimitr_el1 + mrs x0, pmbptr_el1 + mrs x0, pmbsr_el1 + mrs x0, pmbidr_el1 + mrs x0, pmscr_el2 + mrs x0, pmscr_el12 + mrs x0, pmscr_el1 + mrs x0, pmsicr_el1 + mrs x0, pmsirr_el1 + mrs x0, pmsfcr_el1 + mrs x0, pmsevfr_el1 + mrs x0, pmslatfr_el1 + mrs x0, pmsidr_el1 + +// CHECK: mrs x0, PMBLIMITR_EL1 // encoding: [0x00,0x9a,0x38,0xd5] +// CHECK: mrs x0, PMBPTR_EL1 // encoding: [0x20,0x9a,0x38,0xd5] +// CHECK: mrs x0, PMBSR_EL1 // encoding: [0x60,0x9a,0x38,0xd5] +// CHECK: mrs x0, PMBIDR_EL1 // encoding: [0xe0,0x9a,0x38,0xd5] +// CHECK: mrs x0, PMSCR_EL2 // encoding: [0x00,0x99,0x3c,0xd5] +// CHECK: mrs x0, PMSCR_EL12 // encoding: [0x00,0x99,0x3d,0xd5] +// CHECK: mrs x0, PMSCR_EL1 // encoding: [0x00,0x99,0x38,0xd5] +// CHECK: mrs x0, PMSICR_EL1 // encoding: [0x40,0x99,0x38,0xd5] +// CHECK: mrs x0, PMSIRR_EL1 // encoding: [0x60,0x99,0x38,0xd5] +// CHECK: mrs x0, PMSFCR_EL1 // encoding: [0x80,0x99,0x38,0xd5] +// CHECK: mrs x0, PMSEVFR_EL1 // encoding: [0xa0,0x99,0x38,0xd5] +// CHECK: mrs x0, PMSLATFR_EL1 // encoding: [0xc0,0x99,0x38,0xd5] +// CHECK: mrs x0, PMSIDR_EL1 // encoding: [0xe0,0x99,0x38,0xd5] +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register +// NO_SPE: error: expected readable system register diff --git a/test/MC/Disassembler/AArch64/armv8.2a-statistical-profiling.txt b/test/MC/Disassembler/AArch64/armv8.2a-statistical-profiling.txt new file mode 100644 index 00000000000..e83d750e715 --- /dev/null +++ b/test/MC/Disassembler/AArch64/armv8.2a-statistical-profiling.txt @@ -0,0 +1,91 @@ +# RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+spe --disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple aarch64-none-linux-gnu --disassemble < %s | FileCheck --check-prefix=NO_SPE %s + +[0x1f,0x22,0x03,0xd5] +# CHECK: hint #0x10 +# NO_SPE: hint #0x10 + +[0x3f,0x22,0x03,0xd5] +# CHECK: psb csync +# NO_SPE: hint #0x11 + +[0x00,0x9a,0x18,0xd5] +[0x20,0x9a,0x18,0xd5] +[0x60,0x9a,0x18,0xd5] +[0xe0,0x9a,0x18,0xd5] +[0x00,0x99,0x1c,0xd5] +[0x00,0x99,0x1d,0xd5] +[0x00,0x99,0x18,0xd5] +[0x40,0x99,0x18,0xd5] +[0x60,0x99,0x18,0xd5] +[0x80,0x99,0x18,0xd5] +[0xa0,0x99,0x18,0xd5] +[0xc0,0x99,0x18,0xd5] +[0xe0,0x99,0x18,0xd5] +# CHECK: msr PMBLIMITR_EL1, x0 +# NO_SPE: msr S3_0_C9_C10_0, x0 +# CHECK: msr PMBPTR_EL1, x0 +# NO_SPE: msr S3_0_C9_C10_1, x0 +# CHECK: msr PMBSR_EL1, x0 +# NO_SPE: msr S3_0_C9_C10_3, x0 +# CHECK: msr PMBIDR_EL1, x0 +# NO_SPE: msr S3_0_C9_C10_7, x0 +# CHECK: msr PMSCR_EL2, x0 +# NO_SPE: msr S3_4_C9_C9_0, x0 +# CHECK: msr PMSCR_EL12, x0 +# NO_SPE: msr S3_5_C9_C9_0, x0 +# CHECK: msr PMSCR_EL1, x0 +# NO_SPE: msr S3_0_C9_C9_0, x0 +# CHECK: msr PMSICR_EL1, x0 +# NO_SPE: msr S3_0_C9_C9_2, x0 +# CHECK: msr PMSIRR_EL1, x0 +# NO_SPE: msr S3_0_C9_C9_3, x0 +# CHECK: msr PMSFCR_EL1, x0 +# NO_SPE: msr S3_0_C9_C9_4, x0 +# CHECK: msr PMSEVFR_EL1, x0 +# NO_SPE: msr S3_0_C9_C9_5, x0 +# CHECK: msr PMSLATFR_EL1, x0 +# NO_SPE: msr S3_0_C9_C9_6, x0 +# CHECK: msr PMSIDR_EL1, x0 +# NO_SPE: msr S3_0_C9_C9_7, x0 + +[0x00,0x9a,0x38,0xd5] +[0x20,0x9a,0x38,0xd5] +[0x60,0x9a,0x38,0xd5] +[0xe0,0x9a,0x38,0xd5] +[0x00,0x99,0x3c,0xd5] +[0x00,0x99,0x3d,0xd5] +[0x00,0x99,0x38,0xd5] +[0x40,0x99,0x38,0xd5] +[0x60,0x99,0x38,0xd5] +[0x80,0x99,0x38,0xd5] +[0xa0,0x99,0x38,0xd5] +[0xc0,0x99,0x38,0xd5] +[0xe0,0x99,0x38,0xd5] + +# CHECK: mrs x0, PMBLIMITR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C10_0 +# CHECK: mrs x0, PMBPTR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C10_1 +# CHECK: mrs x0, PMBSR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C10_3 +# CHECK: mrs x0, PMBIDR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C10_7 +# CHECK: mrs x0, PMSCR_EL2 +# NO_SPE: mrs x0, S3_4_C9_C9_0 +# CHECK: mrs x0, PMSCR_EL12 +# NO_SPE: mrs x0, S3_5_C9_C9_0 +# CHECK: mrs x0, PMSCR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C9_0 +# CHECK: mrs x0, PMSICR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C9_2 +# CHECK: mrs x0, PMSIRR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C9_3 +# CHECK: mrs x0, PMSFCR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C9_4 +# CHECK: mrs x0, PMSEVFR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C9_5 +# CHECK: mrs x0, PMSLATFR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C9_6 +# CHECK: mrs x0, PMSIDR_EL1 +# NO_SPE: mrs x0, S3_0_C9_C9_7 diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 4b543d3f9fc..a954998d36e 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -901,7 +901,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { break; // No conditions on this operand at all } Cond = Target.getName() + ClassName + "ValidateMCOperand(" + - Op + ", " + llvm::utostr(Entry) + ")"; + Op + ", STI, " + llvm::utostr(Entry) + ")"; } // for all subcases of ResultOperand::K_Record: IAP.addCond(Cond); @@ -996,8 +996,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { if (!MCOpPredicates.empty()) O << "static bool " << Target.getName() << ClassName - << "ValidateMCOperand(\n" - << " const MCOperand &MCOp, unsigned PredicateIndex);\n"; + << "ValidateMCOperand(const MCOperand &MCOp,\n" + << " const MCSubtargetInfo &STI,\n" + << " unsigned PredicateIndex);\n"; O << HeaderO.str(); O.indent(2) << "const char *AsmString;\n"; @@ -1069,8 +1070,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { if (!MCOpPredicates.empty()) { O << "static bool " << Target.getName() << ClassName - << "ValidateMCOperand(\n" - << " const MCOperand &MCOp, unsigned PredicateIndex) {\n" + << "ValidateMCOperand(const MCOperand &MCOp,\n" + << " const MCSubtargetInfo &STI,\n" + << " unsigned PredicateIndex) {\n" << " switch (PredicateIndex) {\n" << " default:\n" << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n" -- 2.34.1