diff --git a/clang/test/Driver/aarch64-lrcpc3.c b/clang/test/Driver/aarch64-lrcpc3.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/aarch64-lrcpc3.c @@ -0,0 +1,26 @@ +// Test that target feature FEAT_RCPC3 is implemented and available correctly + +// FEAT_RCPC3 is optional for v8.2a onwards, and can be enabled with +rcpc3 +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.9-a %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.9-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=ENABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.9-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.4-a %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.4-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=ENABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9.4-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED + +// FEAT_RCPC3 is optional (off by default) for v8.8a/9.3a and older, and can be enabled using +rcpc3 +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.2-a %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.2-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=ENABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.2-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9-a %s 2>&1 | FileCheck %s --check-prefix=NOT_ENABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=ENABLED +// RUN: %clang -### -target aarch64-none-none-eabi -march=armv9-a+norcpc3 %s 2>&1 | FileCheck %s --check-prefix=DISABLED + +// FEAT_RCPC3 is invalid before v8 +// RUN: %clang -### -target arm-none-none-eabi -march=armv7-a+rcpc3 %s 2>&1 | FileCheck %s --check-prefix=INVALID + +// INVALID: error: unsupported argument 'armv7-a+rcpc3' to option '-march=' +// ENABLED: "-target-feature" "+rcpc3" +// NOT_ENABLED-NOT: "-target-feature" "+rcpc3" +// DISABLED: "-target-feature" "-rcpc3" + 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 @@ -77,6 +77,7 @@ AEK_B16B16 = 1ULL << 46, // FEAT_B16B16 AEK_SMEF16F16 = 1ULL << 47, // FEAT_SMEF16F16 AEK_CSSC = 1ULL << 48, // FEAT_CSSC + AEK_RCPC3 = 1ULL << 49, // FEAT_LRCPC3 }; 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 @@ -152,6 +152,7 @@ AARCH64_ARCH_EXT_NAME("mops", AArch64::AEK_MOPS, "+mops", "-mops") AARCH64_ARCH_EXT_NAME("pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon") AARCH64_ARCH_EXT_NAME("cssc", AArch64::AEK_CSSC, "+cssc", "-cssc") +AARCH64_ARCH_EXT_NAME("rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3") #undef AARCH64_ARCH_EXT_NAME #ifndef AARCH64_CPU_NAME 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 @@ -511,6 +511,10 @@ "true", "Enable Armv9.4-A Instrumentation Extension FEAT_ITE", [FeatureETE, FeatureTRBE]>; +def FeatureRCPC3 : SubtargetFeature<"rcpc3", "HasRCPC3", + "true", "Enable Armv8.9-A RCPC instructions added to A64 and Advanced SIMD and floating-point instruction set (FEAT_LRCPC3)", + [FeatureRCPC_IMMO]>; + //===----------------------------------------------------------------------===// // Architectures. // diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -4552,7 +4552,7 @@ class StoreRelease sz, bit o2, bit L, bit o1, bit o0, RegisterClass regtype, string asm> : LoadStoreExclusiveSimple, Sched<[WriteST]>; @@ -11762,6 +11762,73 @@ // 2022 Armv8.9/Armv9.4 Extensions //---------------------------------------------------------------------------- +//--- +// RCPC instructions (FEAT_LRCPC3) +//--- + +class BaseLRCPC3 size, bit V, bits<2> opc, dag oops, dag iops, + string asm, string operands, string cstr = ""> + : I, + Sched<[WriteAtomic]> { + bits<5> Rt; + bits<5> Rn; + let Inst{31-30} = size; + let Inst{29-24} = {0,1,1,V,0,1}; + let Inst{23-22} = opc; + let Inst{21} = 0b0; + // Inst{20-12} + let Inst{11-10} = 0b10; + let Inst{9-5} = Rn; + let Inst{4-0} = Rt; + + let mayLoad = Inst{22}; + let mayStore = !not(Inst{22}); + let hasSideEffects = 0; +} + +class BaseLRCPC3IntegerLoadStorePair size, bits<2> opc, bits<4> opc2, + dag oops, dag iops, string asm, + string operands, string cstr> + : BaseLRCPC3 { + bits<5> Rt2; + let Inst{20-16} = Rt2; + let Inst{15-12} = opc2; +} + +class BaseLRCPC3IntegerLoadStore size, bits<2> opc, dag oops, dag iops, + string asm, string operands, string cstr> + : BaseLRCPC3 { + let Inst{20-12} = 0b000000000; // imm9 +} + +multiclass LRCPC3NEONLoadStoreUnscaledOffset size, bits<2> opc, RegisterClass regtype, + dag oops, dag iops, string asm> { + def i : BaseLRCPC3 { + bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4 + let Inst{20-12} = simm; + } + + def a : InstAlias(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; +} + +class LRCPC3NEONLdStSingle + : BaseSIMDLdStSingle, + Sched<[]> { + bit Q; + let Inst{31} = 0; + let Inst{30} = Q; + let Inst{23} = 0; + let Inst{20-16} = 0b00001; + let Inst{12} = 0; // S + let Inst{11-10} = 0b01; // size + + let mayLoad = L; + let mayStore = !not(L); + let hasSideEffects = 1; +} + //--- // Instrumentation Extension (FEAT_ITE) //--- 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 @@ -234,6 +234,8 @@ AssemblerPredicateWithAll<(all_of FeatureMOPS), "mops">; def HasITE : Predicate<"Subtarget->hasITE()">, AssemblerPredicateWithAll<(all_of FeatureITE), "ite">; +def HasRCPC3 : Predicate<"Subtarget->hasRCPC3()">, + AssemblerPredicate<(all_of FeatureRCPC3), "rcpc3">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def IsWindows : Predicate<"Subtarget->isTargetWindows()">; @@ -3903,6 +3905,21 @@ def STLRB : StoreRelease <0b00, 1, 0, 0, 1, GPR32, "stlrb">; def STLRH : StoreRelease <0b01, 1, 0, 0, 1, GPR32, "stlrh">; +/* +Aliases for when offset=0. Note that in contrast to LoadAcquire which has a $Rn +of type GPR64sp0, we deliberately choose to make $Rn of type GPR64sp and add an +alias for the case of immediate #0. This is because new STLR versions (from +LRCPC3 extension) do have a non-zero immediate value, so GPR64sp0 is not +appropriate anymore (it parses and discards the optional zero). This is not the +case for LoadAcquire because the new LRCPC3 LDAR instructions are post-indexed, +and the immediate values are not inside the [] brackets and thus not accepted +by GPR64sp0 parser. +*/ +def STLRW0 : InstAlias<"stlr\t$Rt, [$Rn, #0]" , (STLRW GPR32: $Rt, GPR64sp:$Rn)>; +def STLRX0 : InstAlias<"stlr\t$Rt, [$Rn, #0]" , (STLRX GPR64: $Rt, GPR64sp:$Rn)>; +def STLRB0 : InstAlias<"stlrb\t$Rt, [$Rn, #0]", (STLRB GPR32: $Rt, GPR64sp:$Rn)>; +def STLRH0 : InstAlias<"stlrh\t$Rt, [$Rn, #0]", (STLRH GPR32: $Rt, GPR64sp:$Rn)>; + def STLXRW : StoreExclusive<0b10, 0, 0, 0, 1, GPR32, "stlxr">; def STLXRX : StoreExclusive<0b11, 0, 0, 0, 1, GPR64, "stlxr">; def STLXRB : StoreExclusive<0b00, 0, 0, 0, 1, GPR32, "stlxrb">; @@ -3937,6 +3954,12 @@ def STLLRX : StoreRelease <0b11, 1, 0, 0, 0, GPR64, "stllr">; def STLLRB : StoreRelease <0b00, 1, 0, 0, 0, GPR32, "stllrb">; def STLLRH : StoreRelease <0b01, 1, 0, 0, 0, GPR32, "stllrh">; + + // Aliases for when offset=0 + def STLLRW0 : InstAlias<"stllr\t$Rt, [$Rn, #0]", (STLLRW GPR32: $Rt, GPR64sp:$Rn)>; + def STLLRX0 : InstAlias<"stllr\t$Rt, [$Rn, #0]", (STLLRX GPR64: $Rt, GPR64sp:$Rn)>; + def STLLRB0 : InstAlias<"stllrb\t$Rt, [$Rn, #0]", (STLLRB GPR32: $Rt, GPR64sp:$Rn)>; + def STLLRH0 : InstAlias<"stllrh\t$Rt, [$Rn, #0]", (STLLRH GPR32: $Rt, GPR64sp:$Rn)>; } //===----------------------------------------------------------------------===// @@ -8528,6 +8551,53 @@ let DecoderNamespace = "Fallback"; } +//===----------------------------------------------------------------------===// +// RCPC Instructions (FEAT_LRCPC3) +//===----------------------------------------------------------------------===// + +let Predicates = [HasRCPC3] in { + // size opc opc2 + def STILPWpre: BaseLRCPC3IntegerLoadStorePair<0b10, 0b00, 0b0000, (outs GPR64sp:$wback), (ins GPR32:$Rt, GPR32:$Rt2, GPR64sp:$Rn), "stilp", "\t$Rt, $Rt2, [$Rn, #-8]!", "$Rn = $wback">; + def STILPXpre: BaseLRCPC3IntegerLoadStorePair<0b11, 0b00, 0b0000, (outs GPR64sp:$wback), (ins GPR64:$Rt, GPR64:$Rt2, GPR64sp:$Rn), "stilp", "\t$Rt, $Rt2, [$Rn, #-16]!", "$Rn = $wback">; + def STILPW: BaseLRCPC3IntegerLoadStorePair<0b10, 0b00, 0b0001, (outs), (ins GPR32:$Rt, GPR32:$Rt2, GPR64sp:$Rn), "stilp", "\t$Rt, $Rt2, [$Rn]", "">; + def STILPX: BaseLRCPC3IntegerLoadStorePair<0b11, 0b00, 0b0001, (outs), (ins GPR64:$Rt, GPR64:$Rt2, GPR64sp:$Rn), "stilp", "\t$Rt, $Rt2, [$Rn]", "">; + def LDIAPPWpre: BaseLRCPC3IntegerLoadStorePair<0b10, 0b01, 0b0000, (outs GPR64sp:$wback, GPR32:$Rt, GPR32:$Rt2), (ins GPR64sp:$Rn), "ldiapp", "\t$Rt, $Rt2, [$Rn], #8", "$Rn = $wback">; + def LDIAPPXpre: BaseLRCPC3IntegerLoadStorePair<0b11, 0b01, 0b0000, (outs GPR64sp:$wback, GPR64:$Rt, GPR64:$Rt2), (ins GPR64sp:$Rn), "ldiapp", "\t$Rt, $Rt2, [$Rn], #16", "$Rn = $wback">; + def LDIAPPW: BaseLRCPC3IntegerLoadStorePair<0b10, 0b01, 0b0001, (outs GPR32:$Rt, GPR32:$Rt2), (ins GPR64sp0:$Rn), "ldiapp", "\t$Rt, $Rt2, [$Rn]", "">; + def LDIAPPX: BaseLRCPC3IntegerLoadStorePair<0b11, 0b01, 0b0001, (outs GPR64:$Rt, GPR64:$Rt2), (ins GPR64sp0:$Rn), "ldiapp", "\t$Rt, $Rt2, [$Rn]", "">; + + // Aliases for when offset=0 + def : InstAlias<"stilp\t$Rt, $Rt2, [$Rn, #0]", (STILPW GPR32: $Rt, GPR32: $Rt2, GPR64sp:$Rn)>; + def : InstAlias<"stilp\t$Rt, $Rt2, [$Rn, #0]", (STILPX GPR64: $Rt, GPR64: $Rt2, GPR64sp:$Rn)>; + + // size opc + def STLRWpre: BaseLRCPC3IntegerLoadStore<0b10, 0b10, (outs GPR64sp:$wback), (ins GPR32:$Rt, GPR64sp:$Rn), "stlr", "\t$Rt, [$Rn, #-4]!", "$Rn = $wback">; + def STLRXpre: BaseLRCPC3IntegerLoadStore<0b11, 0b10, (outs GPR64sp:$wback), (ins GPR64:$Rt, GPR64sp:$Rn), "stlr", "\t$Rt, [$Rn, #-8]!", "$Rn = $wback">; + def LDAPRWpre: BaseLRCPC3IntegerLoadStore<0b10, 0b11, (outs GPR64sp:$wback, GPR32:$Rt), (ins GPR64sp:$Rn), "ldapr", "\t$Rt, [$Rn], #4", "$Rn = $wback">; + def LDAPRXpre: BaseLRCPC3IntegerLoadStore<0b11, 0b11, (outs GPR64sp:$wback, GPR64:$Rt), (ins GPR64sp:$Rn), "ldapr", "\t$Rt, [$Rn], #8", "$Rn = $wback">; +} + +let Predicates = [HasRCPC3, HasNEON] in { + // size opc regtype + defm STLURb: LRCPC3NEONLoadStoreUnscaledOffset<0b00, 0b00, FPR8 , (outs), (ins FPR8 :$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">; + defm STLURh: LRCPC3NEONLoadStoreUnscaledOffset<0b01, 0b00, FPR16 , (outs), (ins FPR16 :$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">; + defm STLURs: LRCPC3NEONLoadStoreUnscaledOffset<0b10, 0b00, FPR32 , (outs), (ins FPR32 :$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">; + defm STLURd: LRCPC3NEONLoadStoreUnscaledOffset<0b11, 0b00, FPR64 , (outs), (ins FPR64 :$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">; + defm STLURq: LRCPC3NEONLoadStoreUnscaledOffset<0b00, 0b10, FPR128, (outs), (ins FPR128:$Rt, GPR64sp:$Rn, simm9:$simm), "stlur">; + defm LDAPURb: LRCPC3NEONLoadStoreUnscaledOffset<0b00, 0b01, FPR8 , (outs FPR8 :$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">; + defm LDAPURh: LRCPC3NEONLoadStoreUnscaledOffset<0b01, 0b01, FPR16 , (outs FPR16 :$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">; + defm LDAPURs: LRCPC3NEONLoadStoreUnscaledOffset<0b10, 0b01, FPR32 , (outs FPR32 :$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">; + defm LDAPURd: LRCPC3NEONLoadStoreUnscaledOffset<0b11, 0b01, FPR64 , (outs FPR64 :$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">; + defm LDAPURq: LRCPC3NEONLoadStoreUnscaledOffset<0b00, 0b11, FPR128, (outs FPR128:$Rt), (ins GPR64sp:$Rn, simm9:$simm), "ldapur">; + + // L + def STL1: LRCPC3NEONLdStSingle<0b0, (outs), (ins VecListOned:$Vt, VectorIndexD:$Q, GPR64sp:$Rn) , "stl1", "">; + def LDAP1: LRCPC3NEONLdStSingle<0b1, (outs VecListOned:$dst), (ins VecListOned:$Vt, VectorIndexD:$Q, GPR64sp0:$Rn), "ldap1", "$Vt = $dst">; + + // Aliases for when offset=0 + def : InstAlias<"stl1\t$Vt$Q, [$Rn, #0]", (STL1 VecListOned:$Vt, VectorIndexD:$Q, GPR64sp:$Rn)>; +} + include "AArch64InstrAtomics.td" include "AArch64SVEInstrInfo.td" include "AArch64SMEInstrInfo.td" 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 @@ -7547,6 +7547,15 @@ case MCK__HASH_8: ExpectedVal = 8; break; + case MCK__HASH__MINUS_4: + ExpectedVal = -4; + break; + case MCK__HASH__MINUS_8: + ExpectedVal = -8; + break; + case MCK__HASH__MINUS_16: + ExpectedVal = -16; + break; case MCK_MPR: // If the Kind is a token for the MPR register class which has the "za" // register (SME accumulator array), check if the asm is a literal "za" diff --git a/llvm/test/MC/AArch64/arm64-memory.s b/llvm/test/MC/AArch64/arm64-memory.s --- a/llvm/test/MC/AArch64/arm64-memory.s +++ b/llvm/test/MC/AArch64/arm64-memory.s @@ -498,11 +498,23 @@ stlrb w3, [x6] stlrh w3, [x6] + stlr w3, [x6, #0] + stlr x3, [x6, 0] + stlrb w3, [sp] + stlrb w3, [sp, #0] + stlrb w3, [sp, 0] + ; CHECK: stlr w3, [x6] ; encoding: [0xc3,0xfc,0x9f,0x88] ; CHECK: stlr x3, [x6] ; encoding: [0xc3,0xfc,0x9f,0xc8] ; CHECK: stlrb w3, [x6] ; encoding: [0xc3,0xfc,0x9f,0x08] ; CHECK: stlrh w3, [x6] ; encoding: [0xc3,0xfc,0x9f,0x48] +; CHECK: stlr w3, [x6] ; encoding: [0xc3,0xfc,0x9f,0x88] +; CHECK: stlr x3, [x6] ; encoding: [0xc3,0xfc,0x9f,0xc8] +; CHECK: stlrb w3, [sp] ; encoding: [0xe3,0xff,0x9f,0x08] +; CHECK: stlrb w3, [sp] ; encoding: [0xe3,0xff,0x9f,0x08] +; CHECK: stlrb w3, [sp] ; encoding: [0xe3,0xff,0x9f,0x08] + ;----------------------------------------------------------------------------- ; Load-acquire/Store-release exclusive ;----------------------------------------------------------------------------- diff --git a/llvm/test/MC/AArch64/armv8.9a-lrcpc3.s b/llvm/test/MC/AArch64/armv8.9a-lrcpc3.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.9a-lrcpc3.s @@ -0,0 +1,143 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+rcpc3 < %s | FileCheck %s +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.9a -mattr=+rcpc3 < %s | FileCheck %s +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v9.4a -mattr=+rcpc3 < %s | FileCheck %s + +// RUN: not llvm-mc -triple aarch64-none-linux-gnu < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.9a < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v9.4a < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s + + stilp w24, w0, [x16, #-8]! +// CHECK: stilp w24, w0, [x16, #-8]! // encoding: [0x18,0x0a,0x00,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stilp w24, w0, [x16, -8]! +// CHECK: stilp w24, w0, [x16, #-8]! // encoding: [0x18,0x0a,0x00,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stilp x25, x1, [x17, -16]! +// CHECK: stilp x25, x1, [x17, #-16]! // encoding: [0x39,0x0a,0x01,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stilp x25, x1, [x17, #-16]! +// CHECK: stilp x25, x1, [x17, #-16]! // encoding: [0x39,0x0a,0x01,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stilp w26, w2, [x18] +// CHECK: stilp w26, w2, [x18] // encoding: [0x5a,0x1a,0x02,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stilp w26, w2, [x18, #0] +// CHECK: stilp w26, w2, [x18] // encoding: [0x5a,0x1a,0x02,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stilp x27, x3, [sp] +// CHECK: stilp x27, x3, [sp] // encoding: [0xfb,0x1b,0x03,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stilp x27, x3, [sp, 0] +// CHECK: stilp x27, x3, [sp] // encoding: [0xfb,0x1b,0x03,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp w28, w4, [x20], #8 +// CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp w28, w4, [x20, #0], #8 +// CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp w28, w4, [x20], 8 +// CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp w28, w4, [x20, 0], 8 +// CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp x29, x5, [x21], #16 +// CHECK: ldiapp x29, x5, [x21], #16 // encoding: [0xbd,0x0a,0x45,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp x29, x5, [x21], 16 +// CHECK: ldiapp x29, x5, [x21], #16 // encoding: [0xbd,0x0a,0x45,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp w30, w6, [sp] +// CHECK: ldiapp w30, w6, [sp] // encoding: [0xfe,0x1b,0x46,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp w30, w6, [sp, #0] +// CHECK: ldiapp w30, w6, [sp] // encoding: [0xfe,0x1b,0x46,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp xzr, x7, [x23] +// CHECK: ldiapp xzr, x7, [x23] // encoding: [0xff,0x1a,0x47,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldiapp xzr, x7, [x23, 0] +// CHECK: ldiapp xzr, x7, [x23] // encoding: [0xff,0x1a,0x47,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + + stlr w3, [x15, #-4]! +// CHECK: stlr w3, [x15, #-4]! // encoding: [0xe3,0x09,0x80,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stlr w3, [x15, -4]! +// CHECK: stlr w3, [x15, #-4]! // encoding: [0xe3,0x09,0x80,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stlr x3, [x15, #-8]! +// CHECK: stlr x3, [x15, #-8]! // encoding: [0xe3,0x09,0x80,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stlr x3, [sp, -8]! +// CHECK: stlr x3, [sp, #-8]! // encoding: [0xe3,0x0b,0x80,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapr w3, [sp], #4 +// CHECK: ldapr w3, [sp], #4 // encoding: [0xe3,0x0b,0xc0,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapr w3, [x15], 4 +// CHECK: ldapr w3, [x15], #4 // encoding: [0xe3,0x09,0xc0,0x99] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapr x3, [x15], #8 +// CHECK: ldapr x3, [x15], #8 // encoding: [0xe3,0x09,0xc0,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapr x3, [x15], 8 +// CHECK: ldapr x3, [x15], #8 // encoding: [0xe3,0x09,0xc0,0xd9] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + + stlur b3, [x15, #-1] +// CHECK: stlur b3, [x15, #-1] // encoding: [0xe3,0xf9,0x1f,0x1d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stlur h3, [x15, #2] +// CHECK: stlur h3, [x15, #2] // encoding: [0xe3,0x29,0x00,0x5d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stlur s3, [x15, #-3] +// CHECK: stlur s3, [x15, #-3] // encoding: [0xe3,0xd9,0x1f,0x9d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stlur d3, [sp, #4] +// CHECK: stlur d3, [sp, #4] // encoding: [0xe3,0x4b,0x00,0xdd] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stlur q3, [x15, #-5] +// CHECK: stlur q3, [x15, #-5] // encoding: [0xe3,0xb9,0x9f,0x1d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapur b3, [x15, #6] +// CHECK: ldapur b3, [x15, #6] // encoding: [0xe3,0x69,0x40,0x1d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapur h3, [x15, #-7] +// CHECK: ldapur h3, [x15, #-7] // encoding: [0xe3,0x99,0x5f,0x5d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapur s3, [x15, #8] +// CHECK: ldapur s3, [x15, #8] // encoding: [0xe3,0x89,0x40,0x9d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapur d3, [x15, #-9] +// CHECK: ldapur d3, [x15, #-9] // encoding: [0xe3,0x79,0x5f,0xdd] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldapur q3, [sp, #10] +// CHECK: ldapur q3, [sp, #10] // encoding: [0xe3,0xab,0xc0,0x1d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + + stl1 { v3.d }[0], [x15] +// CHECK: stl1 { v3.d }[0], [x15] // encoding: [0xe3,0x85,0x01,0x0d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stl1 { v3.d }[0], [x15, #0] +// CHECK: stl1 { v3.d }[0], [x15] // encoding: [0xe3,0x85,0x01,0x0d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stl1 { v3.d }[1], [sp] +// CHECK: stl1 { v3.d }[1], [sp] // encoding: [0xe3,0x87,0x01,0x4d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + stl1 { v3.d }[1], [sp, 0] +// CHECK: stl1 { v3.d }[1], [sp] // encoding: [0xe3,0x87,0x01,0x4d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldap1 { v3.d }[0], [sp] +// CHECK: ldap1 { v3.d }[0], [sp] // encoding: [0xe3,0x87,0x41,0x0d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldap1 { v3.d }[0], [sp, #0] +// CHECK: ldap1 { v3.d }[0], [sp] // encoding: [0xe3,0x87,0x41,0x0d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldap1 { v3.d }[1], [x15] +// CHECK: ldap1 { v3.d }[1], [x15] // encoding: [0xe3,0x85,0x41,0x4d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 + ldap1 { v3.d }[1], [x15, 0] +// CHECK: ldap1 { v3.d }[1], [x15] // encoding: [0xe3,0x85,0x41,0x4d] +// ERROR-NO-RCPC3: [[@LINE-2]]:16: error: instruction requires: rcpc3 diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.9a-lrcpc3.txt b/llvm/test/MC/Disassembler/AArch64/armv8.9a-lrcpc3.txt new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv8.9a-lrcpc3.txt @@ -0,0 +1,113 @@ +# RUN: llvm-mc -triple aarch64-none-linux-gnu -disassemble -show-encoding -mattr=+rcpc3 < %s | FileCheck %s +# RUN: llvm-mc -triple aarch64-none-linux-gnu -disassemble -show-encoding -mattr=+v8.9a -mattr=+rcpc3 < %s | FileCheck %s +# RUN: llvm-mc -triple aarch64-none-linux-gnu -disassemble -show-encoding -mattr=+v9.4a -mattr=+rcpc3 < %s | FileCheck %s + +# RUN: not llvm-mc -triple aarch64-none-linux-gnu -disassemble < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s +# RUN: not llvm-mc -triple aarch64-none-linux-gnu -disassemble -mattr=+v8.9a < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s +# RUN: not llvm-mc -triple aarch64-none-linux-gnu -disassemble -mattr=+v9.4a < %s 2>&1 | FileCheck --check-prefix=ERROR-NO-RCPC3 %s + +[0x18,0x0a,0x00,0x99] +# CHECK: stilp w24, w0, [x16, #-8]! // encoding: [0x18,0x0a,0x00,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0x18,0x0a,0x00,0x99] +# CHECK: stilp w24, w0, [x16, #-8]! // encoding: [0x18,0x0a,0x00,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0x39,0x0a,0x01,0xd9] +# CHECK: stilp x25, x1, [x17, #-16]! // encoding: [0x39,0x0a,0x01,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0x39,0x0a,0x01,0xd9] +# CHECK: stilp x25, x1, [x17, #-16]! // encoding: [0x39,0x0a,0x01,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0x5a,0x1a,0x02,0x99] +# CHECK: stilp w26, w2, [x18] // encoding: [0x5a,0x1a,0x02,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xfb,0x1b,0x03,0xd9] +# CHECK: stilp x27, x3, [sp] // encoding: [0xfb,0x1b,0x03,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0x9c,0x0a,0x44,0x99] +# CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0x9c,0x0a,0x44,0x99] +# CHECK: ldiapp w28, w4, [x20], #8 // encoding: [0x9c,0x0a,0x44,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xbd,0x0a,0x45,0xd9] +# CHECK: ldiapp x29, x5, [x21], #16 // encoding: [0xbd,0x0a,0x45,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xbd,0x0a,0x45,0xd9] +# CHECK: ldiapp x29, x5, [x21], #16 // encoding: [0xbd,0x0a,0x45,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xfe,0x1b,0x46,0x99] +# CHECK: ldiapp w30, w6, [sp] // encoding: [0xfe,0x1b,0x46,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xff,0x1a,0x47,0xd9] +# CHECK: ldiapp xzr, x7, [x23] // encoding: [0xff,0x1a,0x47,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding + +[0xe3,0x09,0x80,0x99] +# CHECK: stlr w3, [x15, #-4]! // encoding: [0xe3,0x09,0x80,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x09,0x80,0x99] +# CHECK: stlr w3, [x15, #-4]! // encoding: [0xe3,0x09,0x80,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x09,0x80,0xd9] +# CHECK: stlr x3, [x15, #-8]! // encoding: [0xe3,0x09,0x80,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x0b,0x80,0xd9] +# CHECK: stlr x3, [sp, #-8]! // encoding: [0xe3,0x0b,0x80,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x0b,0xc0,0x99] +# CHECK: ldapr w3, [sp], #4 // encoding: [0xe3,0x0b,0xc0,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x09,0xc0,0x99] +# CHECK: ldapr w3, [x15], #4 // encoding: [0xe3,0x09,0xc0,0x99] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x09,0xc0,0xd9] +# CHECK: ldapr x3, [x15], #8 // encoding: [0xe3,0x09,0xc0,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x09,0xc0,0xd9] +# CHECK: ldapr x3, [x15], #8 // encoding: [0xe3,0x09,0xc0,0xd9] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding + +[0xe3,0xf9,0x1f,0x1d] +# CHECK: stlur b3, [x15, #-1] // encoding: [0xe3,0xf9,0x1f,0x1d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x29,0x00,0x5d] +# CHECK: stlur h3, [x15, #2] // encoding: [0xe3,0x29,0x00,0x5d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0xd9,0x1f,0x9d] +# CHECK: stlur s3, [x15, #-3] // encoding: [0xe3,0xd9,0x1f,0x9d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x4b,0x00,0xdd] +# CHECK: stlur d3, [sp, #4] // encoding: [0xe3,0x4b,0x00,0xdd] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0xb9,0x9f,0x1d] +# CHECK: stlur q3, [x15, #-5] // encoding: [0xe3,0xb9,0x9f,0x1d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x69,0x40,0x1d] +# CHECK: ldapur b3, [x15, #6] // encoding: [0xe3,0x69,0x40,0x1d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x99,0x5f,0x5d] +# CHECK: ldapur h3, [x15, #-7] // encoding: [0xe3,0x99,0x5f,0x5d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x89,0x40,0x9d] +# CHECK: ldapur s3, [x15, #8] // encoding: [0xe3,0x89,0x40,0x9d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x79,0x5f,0xdd] +# CHECK: ldapur d3, [x15, #-9] // encoding: [0xe3,0x79,0x5f,0xdd] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0xab,0xc0,0x1d] +# CHECK: ldapur q3, [sp, #10] // encoding: [0xe3,0xab,0xc0,0x1d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding + +[0xe3,0x85,0x01,0x0d] +# CHECK: stl1 { v3.d }[0], [x15] // encoding: [0xe3,0x85,0x01,0x0d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x87,0x01,0x4d] +# CHECK: stl1 { v3.d }[1], [sp] // encoding: [0xe3,0x87,0x01,0x4d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x87,0x41,0x0d] +# CHECK: ldap1 { v3.d }[0], [sp] // encoding: [0xe3,0x87,0x41,0x0d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding +[0xe3,0x85,0x41,0x4d] +# CHECK: ldap1 { v3.d }[1], [x15] // encoding: [0xe3,0x85,0x41,0x4d] +# ERROR-NO-RCPC3: [[@LINE-2]]:2: warning: invalid instruction encoding diff --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp --- a/llvm/unittests/Support/TargetParserTest.cpp +++ b/llvm/unittests/Support/TargetParserTest.cpp @@ -1606,7 +1606,8 @@ AArch64::AEK_SME, AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64, AArch64::AEK_SME2, AArch64::AEK_HBC, AArch64::AEK_MOPS, AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1, AArch64::AEK_SME2p1, - AArch64::AEK_B16B16, AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC}; + AArch64::AEK_B16B16, AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC, + AArch64::AEK_RCPC3}; std::vector Features; @@ -1672,6 +1673,7 @@ EXPECT_TRUE(llvm::is_contained(Features, "+mops")); EXPECT_TRUE(llvm::is_contained(Features, "+perfmon")); EXPECT_TRUE(llvm::is_contained(Features, "+cssc")); + EXPECT_TRUE(llvm::is_contained(Features, "+rcpc3")); // Assuming we listed every extension above, this should produce the same // result. (note that AEK_NONE doesn't have a name so it won't be in the