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 @@ -458,6 +458,9 @@ def FeatureMOPS : SubtargetFeature<"mops", "HasMOPS", "true", "Enable Armv8.8-A memcpy and memset acceleration instructions (FEAT_MOPS)">; +def FeatureNMI : SubtargetFeature<"nmi", "HasNMI", + "true", "Enable Armv8.8-A Non-maskable Interrupts (FEAT_NMI, FEAT_GICv3_NMI)">; + def FeatureBRBE : SubtargetFeature<"brbe", "HasBRBE", "true", "Enable Branch Record Buffer Extension (FEAT_BRBE)">; @@ -588,7 +591,7 @@ def HasV8_8aOps : SubtargetFeature< "v8.8a", "HasV8_8aOps", "true", "Support ARM v8.8a instructions", - [HasV8_7aOps, FeatureHBC, FeatureMOPS]>; + [HasV8_7aOps, FeatureHBC, FeatureMOPS, FeatureNMI]>; def HasV8_9aOps : SubtargetFeature< "v8.9a", "HasV8_9aOps", "true", "Support ARM v8.9a instructions", 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 @@ -440,6 +440,9 @@ // v8.5a Memory Tagging Extension let Requires = [{ {AArch64::FeatureMTE} }] in def : PStateImm0_15<"TCO", 0b011, 0b100>; +// v8.8a Non-Maskable Interrupts +let Requires = [{ {AArch64::FeatureNMI} }] in +def : PStateImm0_1<"ALLINT", 0b001, 0b000, 0b000>; // v9.4a Exception-based event profiling // Name, Op1, Op2, Crm_high def : PStateImm0_1<"PM", 0b001, 0b000, 0b001>; @@ -1751,6 +1754,13 @@ def : RWSysReg<"MPAMSM_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b011>; } // HasMPAM, HasSME +// v8.8a Non-Maskable Interrupts +let Requires = [{ {AArch64::FeatureNMI} }] in { + // Op0 Op1 CRn CRm Op2 + def : RWSysReg<"ALLINT", 0b11, 0b000, 0b0100, 0b0011, 0b000>; + def : ROSysReg<"ICC_NMIAR1_EL1", 0b11, 0b000, 0b1100, 0b1001, 0b101>; // FEAT_GICv3_NMI +} + // v8.9a/v9.4a Memory Attribute Index Enhancement (FEAT_AIE) // Op0 Op1 CRn CRm Op2 def : RWSysReg<"AMAIR2_EL1", 0b11, 0b000, 0b1010, 0b0011, 0b001>; diff --git a/llvm/test/MC/AArch64/armv8.8a-nmi-error.s b/llvm/test/MC/AArch64/armv8.8a-nmi-error.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.8a-nmi-error.s @@ -0,0 +1,36 @@ +// RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=+nmi < %s 2>&1 | FileCheck %s +// RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=+v8.8a < %s 2>&1 | FileCheck %s +// RUN: not llvm-mc -triple aarch64 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=NO_NMI +// RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=-nmi < %s 2>&1 | FileCheck %s --check-prefix=NO_NMI + +msr ALLINT, #1 +msr ALLINT, #2 +msr ALLINT, x3 +mrs x2, ALLINT +mrs x11, icc_nmiar1_el1 +msr icc_nmiar1_el1, x12 + +// CHECK: error: immediate must be an integer in range [0, 1]. +// CHECK-NEXT: msr ALLINT, #2 +// CHECK-NEXT: ^ +// CHECK-NEXT: error: expected writable system register or pstate +// CHECK-NEXT: msr icc_nmiar1_el1, x12 +// CHECK-NEXT: ^ + +// NO_NMI: error: expected writable system register or pstate +// NO_NMI-NEXT: msr {{allint|ALLINT}}, #1 +// NO_NMI-NEXT: ^ +// NO_NMI-NEXT: error: expected writable system register or pstate +// NO_NMI-NEXT: msr {{allint|ALLINT}}, #2 +// NO_NMI-NEXT: ^ +// NO_NMI-NEXT: error: expected writable system register or pstate +// NO_NMI-NEXT: msr {{allint|ALLINT}}, x3 +// NO_NMI-NEXT: ^ +// NO_NMI-NEXT: error: expected readable system register +// NO_NMI-NEXT: mrs x2, {{allint|ALLINT}} +// NO_NMI-NEXT: ^ +// NO_NMI-NEXT: error: expected readable system register +// NO_NMI-NEXT: mrs x11, {{icc_nmiar1_el1|ICC_NMIAR1_EL1}} +// NO_NMI-NEXT: ^ +// NO_NMI-NEXT: error: expected writable system register or pstate +// NO_NMI-NEXT: msr {{icc_nmiar1_el1|ICC_NMIAR1_EL1}}, x12 diff --git a/llvm/test/MC/AArch64/armv8.8a-nmi.s b/llvm/test/MC/AArch64/armv8.8a-nmi.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.8a-nmi.s @@ -0,0 +1,12 @@ +// RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+nmi < %s | FileCheck %s +// RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+v8.8a < %s | FileCheck %s + +mrs x2, ALLINT +msr ALLINT, x3 +msr ALLINT, #1 +mrs x7, ICC_NMIAR1_EL1 + +// CHECK: mrs x2, {{allint|ALLINT}} // encoding: [0x02,0x43,0x38,0xd5] +// CHECK: msr {{allint|ALLINT}}, x3 // encoding: [0x03,0x43,0x18,0xd5] +// CHECK: msr {{allint|ALLINT}}, #1 // encoding: [0x1f,0x41,0x01,0xd5] +// CHECK: mrs x7, {{icc_nmiar1_el1|ICC_NMIAR1_EL1}} // encoding: [0xa7,0xc9,0x38,0xd5] diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.8a-nmi.txt b/llvm/test/MC/Disassembler/AArch64/armv8.8a-nmi.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv8.8a-nmi.txt @@ -0,0 +1,30 @@ +# RUN: llvm-mc -triple=aarch64 -mattr=+nmi -disassemble %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=+v8.8a -disassemble %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck %s --check-prefix=NO-NMI + + +[0x03,0x43,0x38,0xd5] +# CHECK: mrs x3, ALLINT +# NO-NMI: mrs x3, S3_0_C4_C3_0 + +[0x06,0x43,0x18,0xd5] +# CHECK: msr ALLINT, x6 +# NO-NMI: msr S3_0_C4_C3_0, x6 + +[0x1f,0x40,0x01,0xd5] +# CHECK: msr ALLINT, #0 +# NO-NMI: msr S0_1_C4_C0_0, xzr + +[0x1f,0x41,0x01,0xd5] +# CHECK: msr ALLINT, #1 +# NO-NMI: msr S0_1_C4_C1_0, xzr + +# Regression test for a defect, where the bit-pattern, which should have allowed +# only ALLSTATE, allowed SPSel (and others). +[0xbf,0x51,0x00,0xd5] +# CHECK: msr S0_0_C5_C1_5, xzr +# NO-NMI: msr S0_0_C5_C1_5, xzr + +[0xa7,0xc9,0x38,0xd5] +# CHECK: mrs x7, ICC_NMIAR1_EL1 +# NO-NMI: mrs x7, S3_0_C12_C9_5