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">;
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;
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()">;
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">;
bool HasCRC;
bool HasPerfMon;
bool HasFullFP16;
+ bool HasSPE;
// HasZeroCycleRegMove - Has zero-cycle register mov instructions.
bool HasZeroCycleRegMove;
bool hasPerfMon() const { return HasPerfMon; }
bool hasFullFP16() const { return HasFullFP16; }
+ bool hasSPE() const { return HasSPE; }
bool isLittleEndian() const { return IsLittle; }
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);
k_Prefetch,
k_ShiftExtend,
k_FPImm,
- k_Barrier
+ k_Barrier,
+ k_PSBHint,
} Kind;
SMLoc StartLoc, EndLoc;
unsigned Length;
};
+ struct PSBHintOp {
+ unsigned Val;
+ const char *Data;
+ unsigned Length;
+ };
+
struct ShiftExtendOp {
AArch64_AM::ShiftExtendType Type;
unsigned Amount;
struct SysRegOp SysReg;
struct SysCRImmOp SysCRImm;
struct PrefetchOp Prefetch;
+ struct PSBHintOp PSBHint;
struct ShiftExtendOp ShiftExtend;
};
case k_Prefetch:
Prefetch = o.Prefetch;
break;
+ case k_PSBHint:
+ PSBHint = o.PSBHint;
+ break;
case k_ShiftExtend:
ShiftExtend = o.ShiftExtend;
break;
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);
}
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())
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 =
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) {
OS << "<prfop invalid #" << getPrefetch() << ">";
break;
}
+ case k_PSBHint: {
+ OS << getPSBHintName();
+ break;
+ }
case k_ShiftExtend: {
OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #"
<< getShiftExtendAmount();
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
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) {
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);
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, {}},
// 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
}
+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,
// 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,
};
--- /dev/null
+// 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
--- /dev/null
+# 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
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);
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";
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"