diff --git a/llvm/include/llvm/Support/AArch64TargetParser.h b/llvm/include/llvm/Support/AArch64TargetParser.h --- a/llvm/include/llvm/Support/AArch64TargetParser.h +++ b/llvm/include/llvm/Support/AArch64TargetParser.h @@ -64,6 +64,7 @@ AEK_F64MM = 1ULL << 32, AEK_LS64 = 1ULL << 33, AEK_BRBE = 1ULL << 34, + AEK_CSRE = 1ULL << 35, }; enum class ArchKind { diff --git a/llvm/include/llvm/Support/AArch64TargetParser.def b/llvm/include/llvm/Support/AArch64TargetParser.def --- a/llvm/include/llvm/Support/AArch64TargetParser.def +++ b/llvm/include/llvm/Support/AArch64TargetParser.def @@ -108,6 +108,7 @@ AARCH64_ARCH_EXT_NAME("tme", AArch64::AEK_TME, "+tme", "-tme") AARCH64_ARCH_EXT_NAME("ls64", AArch64::AEK_LS64, "+ls64", "-ls64") AARCH64_ARCH_EXT_NAME("brbe", AArch64::AEK_BRBE, "+brbe", "-brbe") +AARCH64_ARCH_EXT_NAME("csre", AArch64::AEK_CSRE, "+csre", "-csre") #undef AARCH64_ARCH_EXT_NAME #ifndef AARCH64_CPU_NAME diff --git a/llvm/lib/Support/AArch64TargetParser.cpp b/llvm/lib/Support/AArch64TargetParser.cpp --- a/llvm/lib/Support/AArch64TargetParser.cpp +++ b/llvm/lib/Support/AArch64TargetParser.cpp @@ -102,6 +102,8 @@ Features.push_back("+rcpc"); if (Extensions & AEK_BRBE) Features.push_back("+brbe"); + if (Extensions & AEK_CSRE) + Features.push_back("+csre"); return true; } diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -415,6 +415,9 @@ def FeatureBRBE : SubtargetFeature<"brbe", "HasBRBE", "true", "Enable Branch Record Buffer Extension">; +def FeatureCSRE : SubtargetFeature<"csre", "HasCSRE", + "true", "Enable Call Stack Recorder Extension">; + def FeatureFineGrainedTraps : SubtargetFeature<"fgt", "HasFineGrainedTraps", "true", "Enable fine grained virtualization traps extension">; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -159,6 +159,8 @@ AssemblerPredicate<(all_of FeatureLS64), "ls64">; def HasBRBE : Predicate<"Subtarget->hasBRBE()">, AssemblerPredicate<(all_of FeatureBRBE), "brbe">; +def HasCSRE : Predicate<"Subtarget->hasCSRE()">, + AssemblerPredicate<(all_of FeatureCSRE), "csre">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def IsWindows : Predicate<"Subtarget->isTargetWindows()">; @@ -805,6 +807,11 @@ def WFIT : RegInputSystemI<0b0000, 0b001, "wfit">; } +def CSR_PDEC: SimpleSystemI<0, (ins), "csr", "\tpdec">, Sched<[WriteSys]> { + let Inst{20-5} = 0b0101101110010000; + let Predicates = [HasCSRE]; +} + } // ARMv8.2-A Dot Product diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -185,6 +185,7 @@ bool HasETE = false; bool HasTRBE = false; bool HasBRBE = false; + bool HasCSRE = false; // HasZeroCycleRegMove - Has zero-cycle register mov instructions. bool HasZeroCycleRegMove = false; diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td --- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td +++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td @@ -1593,6 +1593,22 @@ } } +// Call Stack Recorder system registers +let Requires = [{ {AArch64::FeatureCSRE} }] in { +def : RWSysReg<"CSRCR_EL0", 0b10, 0b011, 0b1000, 0b0000, 0b000>; +def : RWSysReg<"CSRCR_EL1", 0b10, 0b000, 0b1000, 0b0000, 0b000>; +def : RWSysReg<"CSRCR_EL12", 0b10, 0b101, 0b1000, 0b0000, 0b000>; +def : RWSysReg<"CSRCR_EL2", 0b10, 0b100, 0b1000, 0b0000, 0b000>; +def : ROSysReg<"CSRIDR_EL0", 0b10, 0b011, 0b1000, 0b0000, 0b010>; +def : ROSysReg<"CSRPTRIDX_EL0", 0b10, 0b011, 0b1000, 0b0000, 0b011>; +def : ROSysReg<"CSRPTRIDX_EL1", 0b10, 0b000, 0b1000, 0b0000, 0b011>; +def : ROSysReg<"CSRPTRIDX_EL2", 0b10, 0b100, 0b1000, 0b0000, 0b011>; +def : RWSysReg<"CSRPTR_EL0", 0b10, 0b011, 0b1000, 0b0000, 0b001>; +def : RWSysReg<"CSRPTR_EL1", 0b10, 0b000, 0b1000, 0b0000, 0b001>; +def : RWSysReg<"CSRPTR_EL12", 0b10, 0b101, 0b1000, 0b0000, 0b001>; +def : RWSysReg<"CSRPTR_EL2", 0b10, 0b100, 0b1000, 0b0000, 0b001>; +} + // Cyclone specific system registers // Op0 Op1 CRn CRm Op2 let Requires = [{ {AArch64::ProcAppleA7} }] in diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -159,6 +159,7 @@ bool parseSymbolicImmVal(const MCExpr *&ImmVal); bool parseNeonVectorList(OperandVector &Operands); bool parseOptionalMulOperand(OperandVector &Operands); + bool parseKeywordOperand(OperandVector &Operands); bool parseOperand(OperandVector &Operands, bool isCondCode, bool invertCondCode); bool parseImmExpr(int64_t &Out); @@ -3700,6 +3701,17 @@ return Error(getLoc(), "expected 'vl' or '#'"); } +bool AArch64AsmParser::parseKeywordOperand(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + auto Tok = Parser.getTok(); + if (Tok.isNot(AsmToken::Identifier)) + return true; + Operands.push_back(AArch64Operand::CreateToken(Tok.getString(), false, + Tok.getLoc(), getContext())); + Parser.Lex(); + return false; +} + /// parseOperand - Parse a arm instruction operand. For now this parses the /// operand regardless of the mnemonic. bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, @@ -3764,6 +3776,11 @@ if (GotShift != MatchOperand_NoMatch) return GotShift; + // If this is a "csr" instruction, parse its special keyword + // operand as an identifier. + if (Mnemonic == "csr") + return parseKeywordOperand(Operands); + // This was not a register so parse other operands that start with an // identifier (like labels) as expressions and create them as immediates. const MCExpr *IdVal; diff --git a/llvm/test/MC/AArch64/csre.s b/llvm/test/MC/AArch64/csre.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/csre.s @@ -0,0 +1,85 @@ +// RUN: not llvm-mc -triple aarch64 -mattr +csre -show-encoding %s 2>%t | FileCheck %s +// RUN: FileCheck --check-prefix=ERROR %s < %t +// RUN: not llvm-mc -triple aarch64 -show-encoding %s 2>%t +// RUN: FileCheck --check-prefix=ERROR-NO-CSRE %s < %t + +msr CSRCR_EL0, x0 +mrs x1, CSRCR_EL0 +// CHECK: msr CSRCR_EL0, x0 // encoding: [0x00,0x80,0x13,0xd5] +// CHECK: mrs x1, CSRCR_EL0 // encoding: [0x01,0x80,0x33,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:9: error: expected readable system register + +msr CSRCR_EL1, x2 +mrs x3, CSRCR_EL1 +// CHECK: msr CSRCR_EL1, x2 // encoding: [0x02,0x80,0x10,0xd5] +// CHECK: mrs x3, CSRCR_EL1 // encoding: [0x03,0x80,0x30,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:9: error: expected readable system register + +msr CSRCR_EL12, x4 +mrs x5, CSRCR_EL12 +// CHECK: msr CSRCR_EL12, x4 // encoding: [0x04,0x80,0x15,0xd5] +// CHECK: mrs x5, CSRCR_EL12 // encoding: [0x05,0x80,0x35,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:9: error: expected readable system register + +msr CSRCR_EL2, x6 +mrs x7, CSRCR_EL2 +// CHECK: msr CSRCR_EL2, x6 // encoding: [0x06,0x80,0x14,0xd5] +// CHECK: mrs x7, CSRCR_EL2 // encoding: [0x07,0x80,0x34,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:9: error: expected readable system register + +msr CSRIDR_EL0, x8 +mrs x9, CSRIDR_EL0 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x9, CSRIDR_EL0 // encoding: [0x49,0x80,0x33,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:9: error: expected readable system register + +msr CSRPTRIDX_EL0, x10 +mrs x11, CSRPTRIDX_EL0 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x11, CSRPTRIDX_EL0 // encoding: [0x6b,0x80,0x33,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:10: error: expected readable system register + +msr CSRPTR_EL0, x12 +mrs x13, CSRPTR_EL0 +// CHECK: msr CSRPTR_EL0, x12 // encoding: [0x2c,0x80,0x13,0xd5] +// CHECK: mrs x13, CSRPTR_EL0 // encoding: [0x2d,0x80,0x33,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:10: error: expected readable system register + +msr CSRPTR_EL1, x14 +mrs x15, CSRPTR_EL1 +// CHECK: msr CSRPTR_EL1, x14 // encoding: [0x2e,0x80,0x10,0xd5] +// CHECK: mrs x15, CSRPTR_EL1 // encoding: [0x2f,0x80,0x30,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:10: error: expected readable system register + +msr CSRPTR_EL12, x16 +mrs x17, CSRPTR_EL12 +// CHECK: msr CSRPTR_EL12, x16 // encoding: [0x30,0x80,0x15,0xd5] +// CHECK: mrs x17, CSRPTR_EL12 // encoding: [0x31,0x80,0x35,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:10: error: expected readable system register + +msr CSRPTR_EL2, x18 +mrs x19, CSRPTR_EL2 +// CHECK: msr CSRPTR_EL2, x18 // encoding: [0x32,0x80,0x14,0xd5] +// CHECK: mrs x19, CSRPTR_EL2 // encoding: [0x33,0x80,0x34,0xd5] +// ERROR-NO-CSRE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-CSRE: [[@LINE-4]]:10: error: expected readable system register + +csr pdec +// CHECK: csr pdec // encoding: [0x1f,0x72,0x0b,0xd5] +// ERROR-NO-CSRE: [[@LINE-2]]:1: error: instruction requires: csre + +csr pduc +// ERROR: [[@LINE-1]]:5: error: invalid operand for instruction +csr pdec,1 +// ERROR: [[@LINE-1]]:10: error: invalid operand for instruction +csr +// ERROR: [[@LINE-1]]:1: error: too few operands for instruction diff --git a/llvm/test/MC/Disassembler/AArch64/csre.txt b/llvm/test/MC/Disassembler/AArch64/csre.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/csre.txt @@ -0,0 +1,90 @@ +# RUN: llvm-mc -triple=aarch64 -mattr=+csre -disassemble %s 2> %t | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -disassemble %s 2> %t | FileCheck --check-prefix=NO-CSRE %s + +[0x00,0x80,0x13,0xd5] +[0x01,0x80,0x33,0xd5] +# CHECK: msr CSRCR_EL0, x0 +# CHECK: mrs x1, CSRCR_EL0 +# NO-CSRE: msr S2_3_C8_C0_0, x0 +# NO-CSRE: mrs x1, S2_3_C8_C0_0 + +[0x02,0x80,0x10,0xd5] +[0x03,0x80,0x30,0xd5] +# CHECK: msr CSRCR_EL1, x2 +# CHECK: mrs x3, CSRCR_EL1 +# NO-CSRE: msr S2_0_C8_C0_0, x2 +# NO-CSRE: mrs x3, S2_0_C8_C0_0 + +[0x04,0x80,0x15,0xd5] +[0x05,0x80,0x35,0xd5] +# CHECK: msr CSRCR_EL12, x4 +# CHECK: mrs x5, CSRCR_EL12 +# NO-CSRE: msr S2_5_C8_C0_0, x4 +# NO-CSRE: mrs x5, S2_5_C8_C0_0 + +[0x06,0x80,0x14,0xd5] +[0x07,0x80,0x34,0xd5] +# CHECK: msr CSRCR_EL2, x6 +# CHECK: mrs x7, CSRCR_EL2 +# NO-CSRE: msr S2_4_C8_C0_0, x6 +# NO-CSRE: mrs x7, S2_4_C8_C0_0 + +[0x48,0x80,0x13,0xd5] # expect failure: CSRIDR_EL0 is RO +[0x49,0x80,0x33,0xd5] +# CHECK: msr S2_3_C8_C0_2, x8 +# CHECK: mrs x9, CSRIDR_EL0 +# NO-CSRE: msr S2_3_C8_C0_2, x8 +# NO-CSRE: mrs x9, S2_3_C8_C0_2 + +[0x6a,0x80,0x13,0xd5] # expect failure: CSRPTRIDX_EL0 is RO +[0x6b,0x80,0x33,0xd5] +# CHECK: msr S2_3_C8_C0_3, x10 +# CHECK: mrs x11, CSRPTRIDX_EL0 +# NO-CSRE: msr S2_3_C8_C0_3, x10 +# NO-CSRE: mrs x11, S2_3_C8_C0_3 + +[0x6a,0x80,0x10,0xd5] # expect failure: CSRPTRIDX_EL1 is RO +[0x6b,0x80,0x30,0xd5] +# CHECK: msr S2_0_C8_C0_3, x10 +# CHECK: mrs x11, CSRPTRIDX_EL1 +# NO-CSRE: msr S2_0_C8_C0_3, x10 +# NO-CSRE: mrs x11, S2_0_C8_C0_3 + +[0x6a,0x80,0x14,0xd5] # expect failure: CSRPTRIDX_EL2 is RO +[0x6b,0x80,0x34,0xd5] +# CHECK: msr S2_4_C8_C0_3, x10 +# CHECK: mrs x11, CSRPTRIDX_EL2 +# NO-CSRE: msr S2_4_C8_C0_3, x10 +# NO-CSRE: mrs x11, S2_4_C8_C0_3 + +[0x2c,0x80,0x13,0xd5] +[0x2d,0x80,0x33,0xd5] +# CHECK: msr CSRPTR_EL0, x12 +# CHECK: mrs x13, CSRPTR_EL0 +# NO-CSRE: msr S2_3_C8_C0_1, x12 +# NO-CSRE: mrs x13, S2_3_C8_C0_1 + +[0x2e,0x80,0x10,0xd5] +[0x2f,0x80,0x30,0xd5] +# CHECK: msr CSRPTR_EL1, x14 +# CHECK: mrs x15, CSRPTR_EL1 +# NO-CSRE: msr S2_0_C8_C0_1, x14 +# NO-CSRE: mrs x15, S2_0_C8_C0_1 + +[0x30,0x80,0x15,0xd5] +[0x31,0x80,0x35,0xd5] +# CHECK: msr CSRPTR_EL12, x16 +# CHECK: mrs x17, CSRPTR_EL12 +# NO-CSRE: msr S2_5_C8_C0_1, x16 +# NO-CSRE: mrs x17, S2_5_C8_C0_1 + +[0x32,0x80,0x14,0xd5] +[0x33,0x80,0x34,0xd5] +# CHECK: msr CSRPTR_EL2, x18 +# CHECK: mrs x19, CSRPTR_EL2 +# NO-CSRE: msr S2_4_C8_C0_1, x18 +# NO-CSRE: mrs x19, S2_4_C8_C0_1 + +[0x1f,0x72,0x0b,0xd5] +# CHECK: csr pdec +# NO-CSRE: sys #3, c7, c2, #0