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 @@ -397,6 +397,15 @@ def FeatureMatMulFP64 : SubtargetFeature<"f64mm", "HasMatMulFP64", "true", "Enable Matrix Multiply FP64 Extension", [FeatureSVE]>; +def FeatureXS : SubtargetFeature<"xs", "HasXS", + "true", "Enable Armv8.7-A limited-TLB-maintenance instruction">; + +def FeatureWFxT : SubtargetFeature<"wfxt", "HasWFxT", + "true", "Enable Armv8.7-A WFET and WFIT instruction">; + +def FeatureHCX : SubtargetFeature< + "hcx", "HasHCX", "true", "Enable Armv8.7-A HCRX_EL2 system register">; + def FeatureFineGrainedTraps : SubtargetFeature<"fgt", "HasFineGrainedTraps", "true", "Enable fine grained virtualization traps extension">; @@ -439,7 +448,7 @@ def HasV8_7aOps : SubtargetFeature< "v8.7a", "HasV8_7aOps", "true", "Support ARM v8.7a instructions", - [HasV8_6aOps]>; + [HasV8_6aOps, FeatureXS, FeatureWFxT, FeatureHCX]>; def HasV8_0rOps : SubtargetFeature< "v8r", "HasV8_0rOps", "true", "Support ARM v8r instructions", 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 @@ -151,6 +151,10 @@ AssemblerPredicate<(all_of FeatureMatMulFP32), "f32mm">; def HasMatMulFP64 : Predicate<"Subtarget->hasMatMulFP64()">, AssemblerPredicate<(all_of FeatureMatMulFP64), "f64mm">; +def HasXS : Predicate<"Subtarget->hasXS()">, + AssemblerPredicate<(all_of FeatureXS), "xs">; +def HasWFxT : Predicate<"Subtarget->hasWFxT()">, + AssemblerPredicate<(all_of FeatureWFxT), "wfxt">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def IsWindows : Predicate<"Subtarget->isTargetWindows()">; @@ -786,11 +790,13 @@ let Predicates = [HasTRACEV8_4]; } -let Predicates = [HasV8_7a] in { def DSBnXS : CRmSystemI { let CRm{1-0} = 0b11; let Inst{9-8} = 0b10; + let Predicates = [HasXS]; } + +let Predicates = [HasWFxT] in { def WFET : RegInputSystemI<0b0000, 0b000, "wfet">; def WFIT : RegInputSystemI<0b0000, 0b001, "wfit">; } 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 @@ -167,6 +167,11 @@ bool HasFineGrainedTraps = false; bool HasEnhancedCounterVirtualization = false; + // Armv8.7-A Extensions + bool HasXS = false; + bool HasWFxT = false; + bool HasHCX = false; + // Arm SVE2 extensions bool HasSVE2 = false; bool HasSVE2AES = false; @@ -491,6 +496,9 @@ bool hasTRACEV8_4() const { return HasTRACEV8_4; } bool hasAM() const { return HasAM; } bool hasAMVS() const { return HasAMVS; } + bool hasXS() const { return HasXS; } + bool hasWFxT() const { return HasWFxT; } + bool hasHCX() const { return HasHCX; } bool hasSEL2() const { return HasSEL2; } bool hasPMU() const { return HasPMU; } bool hasTLB_RMI() const { return HasTLB_RMI; } 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 @@ -821,7 +821,7 @@ def : RWSysReg<"ACTLR_EL3", 0b11, 0b110, 0b0001, 0b0000, 0b001>; def : RWSysReg<"HCR_EL2", 0b11, 0b100, 0b0001, 0b0001, 0b000>; def : RWSysReg<"HCRX_EL2", 0b11, 0b100, 0b0001, 0b0010, 0b010> { - let Requires = [{ {AArch64::HasV8_7aOps} }]; + let Requires = [{ {AArch64::FeatureHCX} }]; } def : RWSysReg<"SCR_EL3", 0b11, 0b110, 0b0001, 0b0001, 0b000>; def : RWSysReg<"MDCR_EL2", 0b11, 0b100, 0b0001, 0b0001, 0b001>; 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 @@ -2925,7 +2925,7 @@ Str += "ARMv8.5a"; else if (FBS[AArch64::HasV8_6aOps]) Str += "ARMv8.6a"; - else if (FBS[AArch64::HasV8_7aOps]) + else if (FBS[AArch64::HasV8_7aOps] || FBS[AArch64::FeatureXS]) Str += "ARMv8.7a"; else { auto ext = std::find_if(std::begin(ExtensionMap), @@ -3016,7 +3016,9 @@ const AArch64TLBI::TLBI TLBI( TLBIorig->Name, TLBIorig->Encoding | (HasnXSQualifier ? (1 << 7) : 0), TLBIorig->NeedsReg, - TLBIorig->FeaturesRequired); + HasnXSQualifier + ? TLBIorig->FeaturesRequired | FeatureBitset({AArch64::FeatureXS}) + : TLBIorig->FeaturesRequired); if (!TLBI.haveFeatures(getSTI().getFeatureBits())) { std::string Name = std::string(TLBI.Name) + (HasnXSQualifier ? "nXS" : ""); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -852,6 +852,8 @@ } else if (CnVal == 8 || CnVal == 9) { // TLBI aliases if (CnVal == 9) { + if (!STI.hasFeature(AArch64::FeatureXS)) + return false; Encoding &= ~(1 << 7); } diff --git a/llvm/test/MC/AArch64/armv8.7a-general.s b/llvm/test/MC/AArch64/armv8.7a-general.s deleted file mode 100644 --- a/llvm/test/MC/AArch64/armv8.7a-general.s +++ /dev/null @@ -1,46 +0,0 @@ -// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.7a < %s 2>%t | FileCheck %s -// RUN: FileCheck --check-prefix=CHECK-ERR --check-prefix=CHECK-V87-ERR %s < %t -// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2> %t -// RUN: FileCheck --check-prefix=CHECK-ERR --check-prefix=CHECK-NO-V87-ERR %s < %t - - mrs x2, HCRX_EL2 -// CHECK: mrs x2, HCRX_EL2 // encoding: [0x42,0x12,0x3c,0xd5] -// CHECK-NO-V87-ERR: [[@LINE-2]]:11: error: expected readable system register - - msr HCRX_EL2, x3 -// CHECK: msr HCRX_EL2, x3 // encoding: [0x43,0x12,0x1c,0xd5] -// CHECK-NO-V87-ERR: [[@LINE-2]]:7: error: expected writable system register - - dsb #16 - dsb #20 - dsb #24 - dsb #28 - dsb oshnxs - dsb nshnxs - dsb ishnxs - dsb synxs -// CHECK: dsb oshnxs // encoding: [0x3f,0x32,0x03,0xd5] -// CHECK: dsb nshnxs // encoding: [0x3f,0x36,0x03,0xd5] -// CHECK: dsb ishnxs // encoding: [0x3f,0x3a,0x03,0xd5] -// CHECK: dsb synxs // encoding: [0x3f,0x3e,0x03,0xd5] -// CHECK: dsb oshnxs // encoding: [0x3f,0x32,0x03,0xd5] -// CHECK: dsb nshnxs // encoding: [0x3f,0x36,0x03,0xd5] -// CHECK: dsb ishnxs // encoding: [0x3f,0x3a,0x03,0xd5] -// CHECK: dsb synxs // encoding: [0x3f,0x3e,0x03,0xd5] -// CHECK-NO-V87-ERR: [[@LINE-16]]:3: error: instruction requires: armv8.7a -// CHECK-NO-V87-ERR: [[@LINE-16]]:3: error: instruction requires: armv8.7a -// CHECK-NO-V87-ERR: [[@LINE-16]]:3: error: instruction requires: armv8.7a -// CHECK-NO-V87-ERR: [[@LINE-16]]:3: error: instruction requires: armv8.7a -// CHECK-NO-V87-ERR: [[@LINE-16]]:3: error: instruction requires: armv8.7a -// CHECK-NO-V87-ERR: [[@LINE-16]]:3: error: instruction requires: armv8.7a -// CHECK-NO-V87-ERR: [[@LINE-16]]:3: error: instruction requires: armv8.7a -// CHECK-NO-V87-ERR: [[@LINE-16]]:3: error: instruction requires: armv8.7a - - dsb #17 - dsb nshstnxs -// CHECK-ERR: [[@LINE-2]]:8: error: barrier operand out of range -// CHECK-ERR: [[@LINE-2]]:7: error: invalid barrier option for DSBnXS instruction - - wfet x17 -// CHECK: wfet x17 // encoding: [0x11,0x10,0x03,0xd5] -// CHECK-NO-V87-ERR: [[@LINE-2]]:3: error: instruction requires: armv8.7a diff --git a/llvm/test/MC/AArch64/armv8.7a-hcx.s b/llvm/test/MC/AArch64/armv8.7a-hcx.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.7a-hcx.s @@ -0,0 +1,12 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+hcx < %s 2>%t | FileCheck %s +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.7a < %s 2>%t | FileCheck %s +// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NO-HCX-ERR %s < %t + + mrs x2, HCRX_EL2 +// CHECK: mrs x2, HCRX_EL2 // encoding: [0x42,0x12,0x3c,0xd5] +// CHECK-NO-HCX-ERR: [[@LINE-2]]:11: error: expected readable system register + + msr HCRX_EL2, x3 +// CHECK: msr HCRX_EL2, x3 // encoding: [0x43,0x12,0x1c,0xd5] +// CHECK-NO-HCX-ERR: [[@LINE-2]]:7: error: expected writable system register diff --git a/llvm/test/MC/AArch64/armv8.7a-wfxt.s b/llvm/test/MC/AArch64/armv8.7a-wfxt.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.7a-wfxt.s @@ -0,0 +1,12 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+wfxt < %s | FileCheck %s +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.7a < %s | FileCheck %s +// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-NO-WFxT-ERR %s < %t + + wfet x17 +// CHECK: wfet x17 // encoding: [0x11,0x10,0x03,0xd5] +// CHECK-NO-WFxT-ERR: [[@LINE-2]]:3: error: instruction requires: wfxt + + wfit x3 +// CHECK: wfit x3 // encoding: [0x23,0x10,0x03,0xd5] +// CHECK-NO-WFxT-ERR: [[@LINE-2]]:3: error: instruction requires: wfxt diff --git a/llvm/test/MC/AArch64/armv8.7a-xs.s b/llvm/test/MC/AArch64/armv8.7a-xs.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.7a-xs.s @@ -0,0 +1,43 @@ +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.4a,+xs < %s 2>%t | FileCheck %s +// RUN: FileCheck --check-prefix=CHECK-ERR --check-prefix=CHECK-XS-ERR %s < %t +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.7a < %s 2>%t | FileCheck %s +// RUN: FileCheck --check-prefix=CHECK-ERR --check-prefix=CHECK-XS-ERR %s < %t +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.4a < %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-ERR --check-prefix=CHECK-NO-XS-ERR %s < %t + + dsb #16 + dsb #20 + dsb #24 + dsb #28 + dsb oshnxs + dsb nshnxs + dsb ishnxs + dsb synxs +// CHECK: dsb oshnxs // encoding: [0x3f,0x32,0x03,0xd5] +// CHECK: dsb nshnxs // encoding: [0x3f,0x36,0x03,0xd5] +// CHECK: dsb ishnxs // encoding: [0x3f,0x3a,0x03,0xd5] +// CHECK: dsb synxs // encoding: [0x3f,0x3e,0x03,0xd5] +// CHECK: dsb oshnxs // encoding: [0x3f,0x32,0x03,0xd5] +// CHECK: dsb nshnxs // encoding: [0x3f,0x36,0x03,0xd5] +// CHECK: dsb ishnxs // encoding: [0x3f,0x3a,0x03,0xd5] +// CHECK: dsb synxs // encoding: [0x3f,0x3e,0x03,0xd5] +// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs +// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs +// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs +// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs +// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs +// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs +// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs +// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs + + dsb #17 + dsb nshstnxs +// CHECK-ERR: [[@LINE-2]]:8: error: barrier operand out of range +// CHECK-ERR: [[@LINE-2]]:7: error: invalid barrier option for DSBnXS instruction + + tlbi vmalle1osnxs + tlbi ipas2e1isnxs, x1 +// CHECK: tlbi vmalle1osnxs // encoding: [0x1f,0x91,0x08,0xd5] +// CHECK: tlbi ipas2e1isnxs, x1 // encoding: [0x21,0x90,0x0c,0xd5] +// CHECK-NO-XS-ERR: [[@LINE-4]]:8: error: TLBI VMALLE1OSnXS requires ARMv8.7a +// CHECK-NO-XS-ERR: [[@LINE-4]]:8: error: TLBI IPAS2E1ISnXS requires ARMv8.7a diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.7a-general.txt b/llvm/test/MC/Disassembler/AArch64/armv8.7a-general.txt deleted file mode 100644 --- a/llvm/test/MC/Disassembler/AArch64/armv8.7a-general.txt +++ /dev/null @@ -1,37 +0,0 @@ -# RUN: llvm-mc -triple=aarch64 -mattr=+v8.7a -disassemble %s | FileCheck %s -# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck --check-prefix=CHECK-NO-V87 %s - -[0x42,0x12,0x3c,0xd5] -# CHECK: mrs x2, HCRX_EL2 -# CHECK-NO-V87: mrs x2, S3_4_C1_C2_2 - -[0x43,0x12,0x1c,0xd5] -# CHECK: msr HCRX_EL2, x3 -# CHECK-NO-V87: msr S3_4_C1_C2_2, x3 - -[0x3f,0x32,0x03,0xd5] -[0x3f,0x36,0x03,0xd5] -[0x3f,0x3a,0x03,0xd5] -[0x3f,0x3e,0x03,0xd5] -# CHECK: dsb oshnxs -# CHECK: dsb nshnxs -# CHECK: dsb ishnxs -# CHECK: dsb synxs -# CHECK-NO-V87: msr S0_3_C3_C2_1, xzr -# CHECK-NO-V87: msr S0_3_C3_C6_1, xzr -# CHECK-NO-V87: msr S0_3_C3_C10_1, xzr -# CHECK-NO-V87: msr S0_3_C3_C14_1, xzr - -[0x3f,0x30,0x03,0xd5] -[0x3f,0x35,0x03,0xd5] -[0x3f,0x3f,0x03,0xd5] -# CHECK: msr S0_3_C3_C0_1, xzr -# CHECK: msr S0_3_C3_C5_1, xzr -# CHECK: msr S0_3_C3_C15_1, xzr -# CHECK-NO-V87: msr S0_3_C3_C0_1, xzr -# CHECK-NO-V87: msr S0_3_C3_C5_1, xzr -# CHECK-NO-V87: msr S0_3_C3_C15_1, xzr - -[0x11,0x10,0x03,0xd5] -# CHECK: wfet x17 -# CHECK-NO-V87: msr S0_3_C1_C0_0, x17 diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.7a-hcx.txt b/llvm/test/MC/Disassembler/AArch64/armv8.7a-hcx.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv8.7a-hcx.txt @@ -0,0 +1,11 @@ +# RUN: llvm-mc -triple=aarch64 -mattr=+hcx -disassemble %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=+v8.7a -disassemble %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck --check-prefix=CHECK-NO-HCX %s + +[0x42,0x12,0x3c,0xd5] +# CHECK: mrs x2, HCRX_EL2 +# CHECK-NO-HCX: mrs x2, S3_4_C1_C2_2 + +[0x43,0x12,0x1c,0xd5] +# CHECK: msr HCRX_EL2, x3 +# CHECK-NO-HCX: msr S3_4_C1_C2_2, x3 diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.7a-wfxt.txt b/llvm/test/MC/Disassembler/AArch64/armv8.7a-wfxt.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv8.7a-wfxt.txt @@ -0,0 +1,11 @@ +# RUN: llvm-mc -triple=aarch64 -mattr=+wfxt -disassemble %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=+v8.7a -disassemble %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck --check-prefix=CHECK-NO-WFxT %s + +[0x11,0x10,0x03,0xd5] +# CHECK: wfet x17 +# CHECK-NO-WFxT: msr S0_3_C1_C0_0, x17 + +[0x23,0x10,0x03,0xd5] +# CHECK: wfit x3 +# CHECK-NO-WFxT: msr S0_3_C1_C0_1, x3 diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.7a-xs.txt b/llvm/test/MC/Disassembler/AArch64/armv8.7a-xs.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv8.7a-xs.txt @@ -0,0 +1,33 @@ +# RUN: llvm-mc -triple=aarch64 -mattr=+v8.4a,+xs -disassemble %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=+v8.7a -disassemble %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=+v8.4a -disassemble %s | FileCheck --check-prefix=CHECK-NO-XS %s + +[0x3f,0x32,0x03,0xd5] +[0x3f,0x36,0x03,0xd5] +[0x3f,0x3a,0x03,0xd5] +[0x3f,0x3e,0x03,0xd5] +# CHECK: dsb oshnxs +# CHECK: dsb nshnxs +# CHECK: dsb ishnxs +# CHECK: dsb synxs +# CHECK-NO-XS: msr S0_3_C3_C2_1, xzr +# CHECK-NO-XS: msr S0_3_C3_C6_1, xzr +# CHECK-NO-XS: msr S0_3_C3_C10_1, xzr +# CHECK-NO-XS: msr S0_3_C3_C14_1, xzr + +[0x3f,0x30,0x03,0xd5] +[0x3f,0x35,0x03,0xd5] +[0x3f,0x3f,0x03,0xd5] +# CHECK: msr S0_3_C3_C0_1, xzr +# CHECK: msr S0_3_C3_C5_1, xzr +# CHECK: msr S0_3_C3_C15_1, xzr +# CHECK-NO-XS: msr S0_3_C3_C0_1, xzr +# CHECK-NO-XS: msr S0_3_C3_C5_1, xzr +# CHECK-NO-XS: msr S0_3_C3_C15_1, xzr + +[0x1f,0x91,0x08,0xd5] +[0x21,0x90,0x0c,0xd5] +# CHECK: tlbi vmalle1osnxs +# CHECK: tlbi ipas2e1isnxs, x1 +# CHECK-NO-XS: sys #0, c9, c1, #0 +# CHECK-NO-XS: sys #4, c9, c0, #1, x1