Skip to content

Commit

Permalink
[AArch64] Add ARMv8.2-A Statistical Profiling Extension
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ostannard committed Dec 1, 2015
1 parent 4667071 commit a34e470
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 6 deletions.
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/AArch64.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">;
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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()">;
Expand Down Expand Up @@ -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">;
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/AArch64Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class AArch64Subtarget : public AArch64GenSubtargetInfo {
bool HasCRC;
bool HasPerfMon;
bool HasFullFP16;
bool HasSPE;

// HasZeroCycleRegMove - Has zero-cycle register mov instructions.
bool HasZeroCycleRegMove;
Expand Down Expand Up @@ -124,6 +125,7 @@ class AArch64Subtarget : public AArch64GenSubtargetInfo {

bool hasPerfMon() const { return HasPerfMon; }
bool hasFullFP16() const { return HasFullFP16; }
bool hasSPE() const { return HasSPE; }

bool isLittleEndian() const { return IsLittle; }

Expand Down
73 changes: 72 additions & 1 deletion llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
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);
Expand Down Expand Up @@ -159,7 +160,8 @@ class AArch64Operand : public MCParsedAsmOperand {
k_Prefetch,
k_ShiftExtend,
k_FPImm,
k_Barrier
k_Barrier,
k_PSBHint,
} Kind;

SMLoc StartLoc, EndLoc;
Expand Down Expand Up @@ -227,6 +229,12 @@ class AArch64Operand : public MCParsedAsmOperand {
unsigned Length;
};

struct PSBHintOp {
unsigned Val;
const char *Data;
unsigned Length;
};

struct ShiftExtendOp {
AArch64_AM::ShiftExtendType Type;
unsigned Amount;
Expand All @@ -250,6 +258,7 @@ class AArch64Operand : public MCParsedAsmOperand {
struct SysRegOp SysReg;
struct SysCRImmOp SysCRImm;
struct PrefetchOp Prefetch;
struct PSBHintOp PSBHint;
struct ShiftExtendOp ShiftExtend;
};

Expand Down Expand Up @@ -301,6 +310,9 @@ class AArch64Operand : public MCParsedAsmOperand {
case k_Prefetch:
Prefetch = o.Prefetch;
break;
case k_PSBHint:
PSBHint = o.PSBHint;
break;
case k_ShiftExtend:
ShiftExtend = o.ShiftExtend;
break;
Expand Down Expand Up @@ -392,6 +404,16 @@ class AArch64Operand : public MCParsedAsmOperand {
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);
Expand Down Expand Up @@ -961,6 +983,7 @@ class AArch64Operand : public MCParsedAsmOperand {
}
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())
Expand Down Expand Up @@ -1534,6 +1557,11 @@ class AArch64Operand : public MCParsedAsmOperand {
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 =
Expand Down Expand Up @@ -1730,6 +1758,19 @@ class AArch64Operand : public MCParsedAsmOperand {
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) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ class AArch64InstPrinter : public MCInstPrinter {
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);

Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, {}},
Expand Down Expand Up @@ -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
Expand Down
30 changes: 30 additions & 0 deletions llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
};
Expand Down
Loading

0 comments on commit a34e470

Please sign in to comment.