Index: lib/Target/AArch64/AArch64.td =================================================================== --- lib/Target/AArch64/AArch64.td +++ lib/Target/AArch64/AArch64.td @@ -118,6 +118,9 @@ "disable-latency-sched-heuristic", "DisableLatencySchedHeuristic", "true", "Disable latency scheduling heuristic">; +def FeatureRCPC : SubtargetFeature<"rcpc", "HasRCPC", "true", + "Enable support for RCPC extension">; + def FeatureUseRSqrt : SubtargetFeature< "use-reciprocal-square-root", "UseRSqrt", "true", "Use the reciprocal square root approximation">; @@ -143,7 +146,7 @@ "Support ARM v8.2a instructions", [HasV8_1aOps, FeatureRAS]>; def HasV8_3aOps : SubtargetFeature<"v8.3a", "HasV8_3aOps", "true", - "Support ARM v8.3a instructions", [HasV8_2aOps]>; + "Support ARM v8.3a instructions", [HasV8_2aOps, FeatureRCPC]>; //===----------------------------------------------------------------------===// // Register File Description Index: lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- lib/Target/AArch64/AArch64InstrFormats.td +++ lib/Target/AArch64/AArch64InstrFormats.td @@ -1186,6 +1186,18 @@ (!cast(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; } +let mayLoad = 1 in +class RCPCLoad sz, string asm, RegisterClass RC> + : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, + Sched<[]> { + bits<5> Rn; + bits<5> Rt; + let Inst{31-30} = sz; + let Inst{29-10} = 0b11100010111111110000; + let Inst{9-5} = Rn; + let Inst{4-0} = Rt; +} + //--- // Conditional branch instruction. //--- Index: lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.td +++ lib/Target/AArch64/AArch64InstrInfo.td @@ -44,6 +44,8 @@ "fuse-aes">; def HasSVE : Predicate<"Subtarget->hasSVE()">, AssemblerPredicate<"FeatureSVE", "sve">; +def HasRCPC : Predicate<"Subtarget->hasRCPC()">, + AssemblerPredicate<"FeatureRCPC", "rcpc">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; @@ -500,6 +502,14 @@ } // HasV8_3A +let Predicates = [HasRCPC] in { + // v8.3 Release Consistent Processor Consistent support + def LDAPRB : RCPCLoad<0b00, "ldaprb", GPR32>; + def LDAPRH : RCPCLoad<0b01, "ldaprh", GPR32>; + def LDAPRW : RCPCLoad<0b10, "ldapr", GPR32>; + def LDAPRX : RCPCLoad<0b11, "ldapr", GPR64>; +} + def : InstAlias<"clrex", (CLREX 0xf)>; def : InstAlias<"isb", (ISB 0xf)>; Index: lib/Target/AArch64/AArch64Subtarget.h =================================================================== --- lib/Target/AArch64/AArch64Subtarget.h +++ lib/Target/AArch64/AArch64Subtarget.h @@ -72,6 +72,7 @@ bool HasSPE = false; bool HasLSLFast = false; bool HasSVE = false; + bool HasRCPC = false; // HasZeroCycleRegMove - Has zero-cycle register mov instructions. bool HasZeroCycleRegMove = false; @@ -255,6 +256,7 @@ bool hasSPE() const { return HasSPE; } bool hasLSLFast() const { return HasLSLFast; } bool hasSVE() const { return HasSVE; } + bool hasRCPC() const { return HasRCPC; } bool isLittleEndian() const { return IsLittle; } Index: test/MC/AArch64/armv8.3a-rcpc.s =================================================================== --- /dev/null +++ test/MC/AArch64/armv8.3a-rcpc.s @@ -0,0 +1,17 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.3a < %s 2>&1 | FileCheck %s +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.2a < %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-REQ %s < %t + + ldaprb w0, [x0, #0] + ldaprh w0, [x0, #0] + ldapr w0, [x0, #0] + ldapr x0, [x0, #0] + +// CHECK: ldaprb w0, [x0] // encoding: [0x00,0xc0,0xbf,0x38] +// CHECK: ldaprh w0, [x0] // encoding: [0x00,0xc0,0xbf,0x78] +// CHECK: ldapr w0, [x0] // encoding: [0x00,0xc0,0xbf,0xb8] +// CHECK: ldapr x0, [x0] // encoding: [0x00,0xc0,0xbf,0xf8] +// CHECK-REQ: error: invalid operand for instruction +// CHECK-REQ: error: invalid operand for instruction +// CHECK-REQ: error: invalid operand for instruction +// CHECK-REQ: error: invalid operand for instruction Index: test/MC/Disassembler/AArch64/armv8.3a-rcpc.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/AArch64/armv8.3a-rcpc.txt @@ -0,0 +1,26 @@ +# RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.3a --disassemble < %s | FileCheck %s + +# CHECK: ldaprb w0, [x0] +# CHECK: ldaprh w0, [x0] +# CHECK: ldapr w0, [x0] +# CHECK: ldapr x0, [x0] +[0x00,0xc0,0xbf,0x38] +[0x00,0xc0,0xbf,0x78] +[0x00,0xc0,0xbf,0xb8] +[0x00,0xc0,0xbf,0xf8] + +# RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.2a --disassemble < %s 2>&1 | FileCheck --check-prefix=CHECK-V8_2A %s + +# CHECK-V8_2A: warning: invalid instruction encoding +# CHECK-V8_2A: [0x00,0xc0,0xbf,0x38] +# CHECK-V8_2A: ^ +# CHECK-V8_2A: warning: invalid instruction encoding +# CHECK-V8_2A: [0x00,0xc0,0xbf,0x78] +# CHECK-V8_2A: ^ +# CHECK-V8_2A: warning: invalid instruction encoding +# CHECK-V8_2A: [0x00,0xc0,0xbf,0xb8] +# CHECK-V8_2A: ^ +# CHECK-V8_2A: warning: invalid instruction encoding +# CHECK-V8_2A: [0x00,0xc0,0xbf,0xf8] +# CHECK-V8_2A: ^ +