Index: llvm/trunk/lib/Target/AArch64/AArch64.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64.td +++ llvm/trunk/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">; @@ -147,7 +150,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: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td @@ -1098,6 +1098,18 @@ let Inst{9-5} = 0b11111; } +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: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td @@ -46,6 +46,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()">; @@ -448,6 +450,14 @@ def SDOTIDX4S : BaseSIMDThreeSameVectorDotIndex<1, 0, "sdot", ".4s", ".16b", ".4b">; } +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: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h @@ -73,6 +73,7 @@ bool HasSPE = false; bool HasLSLFast = false; bool HasSVE = false; + bool HasRCPC = false; // HasZeroCycleRegMove - Has zero-cycle register mov instructions. bool HasZeroCycleRegMove = false; @@ -257,6 +258,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: llvm/trunk/test/MC/AArch64/armv8.3a-rcpc.s =================================================================== --- llvm/trunk/test/MC/AArch64/armv8.3a-rcpc.s +++ llvm/trunk/test/MC/AArch64/armv8.3a-rcpc.s @@ -0,0 +1,23 @@ +// 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, [x17, #0] + ldapr w0, [x1, #0] + ldapr x0, [x0, #0] + ldapr w18, [x0] + ldapr x15, [x0] + +// CHECK: ldaprb w0, [x0] // encoding: [0x00,0xc0,0xbf,0x38] +// CHECK: ldaprh w0, [x17] // encoding: [0x20,0xc2,0xbf,0x78] +// CHECK: ldapr w0, [x1] // encoding: [0x20,0xc0,0xbf,0xb8] +// CHECK: ldapr x0, [x0] // encoding: [0x00,0xc0,0xbf,0xf8] +// CHECK: ldapr w18, [x0] // encoding: [0x12,0xc0,0xbf,0xb8] +// CHECK: ldapr x15, [x0] // encoding: [0x0f,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 +// CHECK-REQ: error: instruction requires: rcpc +// CHECK-REQ: error: instruction requires: rcpc Index: llvm/trunk/test/MC/Disassembler/AArch64/armv8.3a-rcpc.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/AArch64/armv8.3a-rcpc.txt +++ llvm/trunk/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: ^ +