[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

llvm-svn: 254401
This commit is contained in:
Oliver Stannard 2015-12-01 10:48:51 +00:00
parent 4667071574
commit a34e47066e
12 changed files with 355 additions and 6 deletions

View File

@ -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">;

View File

@ -911,6 +911,25 @@ def msr_sysreg_op : Operand<i32> {
let PrintMethod = "printMSRSystemRegister";
}
def PSBHintOperand : AsmOperandClass {
let Name = "PSBHint";
let ParserMethod = "tryParsePSBHint";
}
def psbhint_op : Operand<i32> {
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;

View File

@ -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<imm0_15, 0b010, "clrex">;

View File

@ -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; }

View File

@ -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<AArch64Operand> CreatePSBHint(unsigned Val,
StringRef Str,
SMLoc S,
MCContext &Ctx) {
auto Op = make_unique<AArch64Operand>(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<AArch64Operand>
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 << "<prfop invalid #" << getPrefetch() << ">";
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

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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,
};

View File

@ -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

View File

@ -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

View File

@ -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"