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 @@ -63,6 +63,7 @@ AEK_F32MM = 1ULL << 31, AEK_F64MM = 1ULL << 32, AEK_LS64 = 1ULL << 33, + AEK_BRBE = 1ULL << 34, }; 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 @@ -107,6 +107,7 @@ AARCH64_ARCH_EXT_NAME("f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm") 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") #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 @@ -100,6 +100,8 @@ Features.push_back("+sve2-bitperm"); if (Extensions & AEK_RCPC) Features.push_back("+rcpc"); + if (Extensions & AEK_BRBE) + Features.push_back("+brbe"); 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 @@ -412,6 +412,9 @@ def FeatureLS64 : SubtargetFeature<"ls64", "HasLS64", "true", "Enable Armv8.7-A LD64B/ST64B Accelerator Extension">; +def FeatureBRBE : SubtargetFeature<"brbe", "HasBRBE", + "true", "Enable Branch Record Buffer 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 @@ -157,6 +157,8 @@ AssemblerPredicate<(all_of FeatureWFxT), "wfxt">; def HasLS64 : Predicate<"Subtarget->hasLS64()">, AssemblerPredicate<(all_of FeatureLS64), "ls64">; +def HasBRBE : Predicate<"Subtarget->hasBRBE()">, + AssemblerPredicate<(all_of FeatureBRBE), "brbe">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def IsWindows : Predicate<"Subtarget->isTargetWindows()">; 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 @@ -184,6 +184,7 @@ // Future architecture extensions. bool HasETE = false; bool HasTRBE = false; + bool HasBRBE = 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 @@ -1574,6 +1574,25 @@ let Requires = [{ {AArch64::FeatureLS64} }] in def : RWSysReg<"ACCDATA_EL1", 0b11, 0b000, 0b1101, 0b0000, 0b101>; +// Branch Record Buffer system registers +let Requires = [{ {AArch64::FeatureBRBE} }] in { +def : RWSysReg<"BRBCR_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b000>; +def : RWSysReg<"BRBCR_EL12", 0b10, 0b101, 0b1001, 0b0000, 0b000>; +def : RWSysReg<"BRBCR_EL2", 0b10, 0b100, 0b1001, 0b0000, 0b000>; +def : RWSysReg<"BRBFCR_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b001>; +def : ROSysReg<"BRBIDR0_EL1", 0b10, 0b001, 0b1001, 0b0010, 0b000>; +def : RWSysReg<"BRBINFINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b000>; +def : RWSysReg<"BRBSRCINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b001>; +def : RWSysReg<"BRBTGTINJ_EL1", 0b10, 0b001, 0b1001, 0b0001, 0b010>; +def : RWSysReg<"BRBTS_EL1", 0b10, 0b001, 0b1001, 0b0000, 0b010>; +foreach n = 0-31 in { + defvar nb = !cast>(n); + def : ROSysReg<"BRBINF"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b00}>; + def : ROSysReg<"BRBSRC"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b01}>; + def : ROSysReg<"BRBTGT"#n#"_EL1", 0b10, 0b001, 0b1000, nb{3-0}, {nb{4},0b10}>; +} +} + // Cyclone specific system registers // Op0 Op1 CRn CRm Op2 let Requires = [{ {AArch64::ProcAppleA7} }] in diff --git a/llvm/test/MC/AArch64/brbe.s b/llvm/test/MC/AArch64/brbe.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/brbe.s @@ -0,0 +1,135 @@ +// RUN: not llvm-mc -triple aarch64 -mattr +brbe -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-BRBE %s < %t + +msr BRBCR_EL1, x0 +mrs x1, BRBCR_EL1 +// CHECK: msr BRBCR_EL1, x0 // encoding: [0x00,0x90,0x11,0xd5] +// CHECK: mrs x1, BRBCR_EL1 // encoding: [0x01,0x90,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:9: error: expected readable system register + +msr BRBCR_EL12, x2 +mrs x3, BRBCR_EL12 +// CHECK: msr BRBCR_EL12, x2 // encoding: [0x02,0x90,0x15,0xd5] +// CHECK: mrs x3, BRBCR_EL12 // encoding: [0x03,0x90,0x35,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:9: error: expected readable system register + +msr BRBCR_EL2, x4 +mrs x5, BRBCR_EL2 +// CHECK: msr BRBCR_EL2, x4 // encoding: [0x04,0x90,0x14,0xd5] +// CHECK: mrs x5, BRBCR_EL2 // encoding: [0x05,0x90,0x34,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:9: error: expected readable system register + +msr BRBFCR_EL1, x6 +mrs x7, BRBFCR_EL1 +// CHECK: msr BRBFCR_EL1, x6 // encoding: [0x26,0x90,0x11,0xd5] +// CHECK: mrs x7, BRBFCR_EL1 // encoding: [0x27,0x90,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:9: error: expected readable system register + +msr BRBIDR0_EL1, x8 +mrs x9, BRBIDR0_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x9, BRBIDR0_EL1 // encoding: [0x09,0x92,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:9: error: expected readable system register + +msr BRBINFINJ_EL1, x10 +mrs x11, BRBINFINJ_EL1 +// CHECK: msr BRBINFINJ_EL1, x10 // encoding: [0x0a,0x91,0x11,0xd5] +// CHECK: mrs x11, BRBINFINJ_EL1 // encoding: [0x0b,0x91,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBSRCINJ_EL1, x12 +mrs x13, BRBSRCINJ_EL1 +// CHECK: msr BRBSRCINJ_EL1, x12 // encoding: [0x2c,0x91,0x11,0xd5] +// CHECK: mrs x13, BRBSRCINJ_EL1 // encoding: [0x2d,0x91,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBTGTINJ_EL1, x14 +mrs x15, BRBTGTINJ_EL1 +// CHECK: msr BRBTGTINJ_EL1, x14 // encoding: [0x4e,0x91,0x11,0xd5] +// CHECK: mrs x15, BRBTGTINJ_EL1 // encoding: [0x4f,0x91,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBTS_EL1, x16 +mrs x17, BRBTS_EL1 +// CHECK: msr BRBTS_EL1, x16 // encoding: [0x50,0x90,0x11,0xd5] +// CHECK: mrs x17, BRBTS_EL1 // encoding: [0x51,0x90,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +// Rather than testing all 32 registers in the three BRBINF/BRBSRC/BRBTGT +// families, I'll test a representative sample, including all bits clear, +// all bits set, each bit set individually, and a couple of intermediate +// patterns. + +msr BRBINF0_EL1, x18 +mrs x19, BRBINF0_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x19, BRBINF0_EL1 // encoding: [0x13,0x80,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBINF1_EL1, x20 +mrs x21, BRBINF1_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x21, BRBINF1_EL1 // encoding: [0x15,0x81,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBINF2_EL1, x22 +mrs x23, BRBINF2_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x23, BRBINF2_EL1 // encoding: [0x17,0x82,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBSRC4_EL1, x24 +mrs x25, BRBSRC4_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x25, BRBSRC4_EL1 // encoding: [0x39,0x84,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBSRC8_EL1, x26 +mrs x27, BRBSRC8_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x27, BRBSRC8_EL1 // encoding: [0x3b,0x88,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBSRC16_EL1, x28 +mrs x29, BRBSRC16_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x29, BRBSRC16_EL1 // encoding: [0xbd,0x80,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:10: error: expected readable system register + +msr BRBTGT10_EL1, x0 +mrs x1, BRBTGT10_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x1, BRBTGT10_EL1 // encoding: [0x41,0x8a,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:9: error: expected readable system register + +msr BRBTGT21_EL1, x2 +mrs x3, BRBTGT21_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x3, BRBTGT21_EL1 // encoding: [0xc3,0x85,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:9: error: expected readable system register + +msr BRBTGT31_EL1, x4 +mrs x5, BRBTGT31_EL1 +// ERROR: [[@LINE-2]]:5: error: expected writable system register +// CHECK: mrs x5, BRBTGT31_EL1 // encoding: [0xc5,0x8f,0x31,0xd5] +// ERROR-NO-BRBE: [[@LINE-4]]:5: error: expected writable system register +// ERROR-NO-BRBE: [[@LINE-4]]:9: error: expected readable system register diff --git a/llvm/test/MC/Disassembler/AArch64/brbe.txt b/llvm/test/MC/Disassembler/AArch64/brbe.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/brbe.txt @@ -0,0 +1,128 @@ +# RUN: llvm-mc -triple=aarch64 -mattr=+brbe -disassemble %s 2> %t | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -disassemble %s 2> %t | FileCheck --check-prefix=NO-BRBE %s + +[0x00,0x90,0x11,0xd5] +[0x01,0x90,0x31,0xd5] +# CHECK: msr BRBCR_EL1, x0 +# CHECK: mrs x1, BRBCR_EL1 +# NO-BRBE: msr S2_1_C9_C0_0, x0 +# NO-BRBE: mrs x1, S2_1_C9_C0_0 + +[0x02,0x90,0x15,0xd5] +[0x03,0x90,0x35,0xd5] +# CHECK: msr BRBCR_EL12, x2 +# CHECK: mrs x3, BRBCR_EL12 +# NO-BRBE: msr S2_5_C9_C0_0, x2 +# NO-BRBE: mrs x3, S2_5_C9_C0_0 + +[0x04,0x90,0x14,0xd5] +[0x05,0x90,0x34,0xd5] +# CHECK: msr BRBCR_EL2, x4 +# CHECK: mrs x5, BRBCR_EL2 +# NO-BRBE: msr S2_4_C9_C0_0, x4 +# NO-BRBE: mrs x5, S2_4_C9_C0_0 + +[0x26,0x90,0x11,0xd5] +[0x27,0x90,0x31,0xd5] +# CHECK: msr BRBFCR_EL1, x6 +# CHECK: mrs x7, BRBFCR_EL1 +# NO-BRBE: msr S2_1_C9_C0_1, x6 +# NO-BRBE: mrs x7, S2_1_C9_C0_1 + +[0x08,0x92,0x11,0xd5] # expect failure: BRBIDR0_EL1 is RO +[0x09,0x92,0x31,0xd5] +# CHECK: msr S2_1_C9_C2_0, x8 +# CHECK: mrs x9, BRBIDR0_EL1 +# NO-BRBE: msr S2_1_C9_C2_0, x8 +# NO-BRBE: mrs x9, S2_1_C9_C2_0 + +[0x0a,0x91,0x11,0xd5] +[0x0b,0x91,0x31,0xd5] +# CHECK: msr BRBINFINJ_EL1, x10 +# CHECK: mrs x11, BRBINFINJ_EL1 +# NO-BRBE: msr S2_1_C9_C1_0, x10 +# NO-BRBE: mrs x11, S2_1_C9_C1_0 + +[0x2c,0x91,0x11,0xd5] +[0x2d,0x91,0x31,0xd5] +# CHECK: msr BRBSRCINJ_EL1, x12 +# CHECK: mrs x13, BRBSRCINJ_EL1 +# NO-BRBE: msr S2_1_C9_C1_1, x12 +# NO-BRBE: mrs x13, S2_1_C9_C1_1 + +[0x4e,0x91,0x11,0xd5] +[0x4f,0x91,0x31,0xd5] +# CHECK: msr BRBTGTINJ_EL1, x14 +# CHECK: mrs x15, BRBTGTINJ_EL1 +# NO-BRBE: msr S2_1_C9_C1_2, x14 +# NO-BRBE: mrs x15, S2_1_C9_C1_2 + +[0x50,0x90,0x11,0xd5] +[0x51,0x90,0x31,0xd5] +# CHECK: msr BRBTS_EL1, x16 +# CHECK: mrs x17, BRBTS_EL1 +# NO-BRBE: msr S2_1_C9_C0_2, x16 +# NO-BRBE: mrs x17, S2_1_C9_C0_2 + +[0x12,0x80,0x11,0xd5] # expect failure: BRBINF0_EL1 is RO +[0x13,0x80,0x31,0xd5] +# CHECK: msr S2_1_C8_C0_0, x18 +# CHECK: mrs x19, BRBINF0_EL1 +# NO-BRBE: msr S2_1_C8_C0_0, x18 +# NO-BRBE: mrs x19, S2_1_C8_C0_0 + +[0x14,0x81,0x11,0xd5] # expect failure: BRBINF1_EL1 is RO +[0x15,0x81,0x31,0xd5] +# CHECK: msr S2_1_C8_C1_0, x20 +# CHECK: mrs x21, BRBINF1_EL1 +# NO-BRBE: msr S2_1_C8_C1_0, x20 +# NO-BRBE: mrs x21, S2_1_C8_C1_0 + +[0x16,0x82,0x11,0xd5] # expect failure: BRBINF2_EL1 is RO +[0x17,0x82,0x31,0xd5] +# CHECK: msr S2_1_C8_C2_0, x22 +# CHECK: mrs x23, BRBINF2_EL1 +# NO-BRBE: msr S2_1_C8_C2_0, x22 +# NO-BRBE: mrs x23, S2_1_C8_C2_0 + +[0x38,0x84,0x11,0xd5] # expect failure: BRBSRC4_EL1 is RO +[0x39,0x84,0x31,0xd5] +# CHECK: msr S2_1_C8_C4_1, x24 +# CHECK: mrs x25, BRBSRC4_EL1 +# NO-BRBE: msr S2_1_C8_C4_1, x24 +# NO-BRBE: mrs x25, S2_1_C8_C4_1 + +[0x3a,0x88,0x11,0xd5] # expect failure: BRBSRC8_EL1 is RO +[0x3b,0x88,0x31,0xd5] +# CHECK: msr S2_1_C8_C8_1, x26 +# CHECK: mrs x27, BRBSRC8_EL1 +# NO-BRBE: msr S2_1_C8_C8_1, x26 +# NO-BRBE: mrs x27, S2_1_C8_C8_1 + +[0xbc,0x80,0x11,0xd5] # expect failure: BRBSRC16_EL1 is RO +[0xbd,0x80,0x31,0xd5] +# CHECK: msr S2_1_C8_C0_5, x28 +# CHECK: mrs x29, BRBSRC16_EL1 +# NO-BRBE: msr S2_1_C8_C0_5, x28 +# NO-BRBE: mrs x29, S2_1_C8_C0_5 + +[0x40,0x8a,0x11,0xd5] # expect failure: BRBTGT10_EL1 is RO +[0x41,0x8a,0x31,0xd5] +# CHECK: msr S2_1_C8_C10_2, x0 +# CHECK: mrs x1, BRBTGT10_EL1 +# NO-BRBE: msr S2_1_C8_C10_2, x0 +# NO-BRBE: mrs x1, S2_1_C8_C10_2 + +[0xc2,0x85,0x11,0xd5] # expect failure: BRBTGT21_EL1 is RO +[0xc3,0x85,0x31,0xd5] +# CHECK: msr S2_1_C8_C5_6, x2 +# CHECK: mrs x3, BRBTGT21_EL1 +# NO-BRBE: msr S2_1_C8_C5_6, x2 +# NO-BRBE: mrs x3, S2_1_C8_C5_6 + +[0xc4,0x8f,0x11,0xd5] # expect failure: BRBTGT31_EL1 is RO +[0xc5,0x8f,0x31,0xd5] +# CHECK: msr S2_1_C8_C15_6, x4 +# CHECK: mrs x5, BRBTGT31_EL1 +# NO-BRBE: msr S2_1_C8_C15_6, x4 +# NO-BRBE: mrs x5, S2_1_C8_C15_6