Index: lib/Target/AArch64/AArch64.td =================================================================== --- lib/Target/AArch64/AArch64.td +++ lib/Target/AArch64/AArch64.td @@ -32,6 +32,9 @@ def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true", "Enable ARMv8 CRC-32 checksum instructions">; +def FeatureV8_1a : SubtargetFeature<"v8.1a", "HasV8_1a", "true", + "Enable ARMv8.1a extensions", [FeatureCRC]>; + /// Cyclone has register move instructions which are "free". def FeatureZCRegMove : SubtargetFeature<"zcm", "HasZeroCycleRegMove", "true", "Has zero-cycle register moves">; Index: lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.td +++ lib/Target/AArch64/AArch64InstrInfo.td @@ -22,6 +22,8 @@ AssemblerPredicate<"FeatureCrypto", "crypto">; def HasCRC : Predicate<"Subtarget->hasCRC()">, AssemblerPredicate<"FeatureCRC", "crc">; +def HasV8_1a : Predicate<"Subtarget->hasV8_1a()">, + AssemblerPredicate<"FeatureV8_1a", "v8.1a">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def IsCyclone : Predicate<"Subtarget->isCyclone()">; Index: lib/Target/AArch64/AArch64Subtarget.h =================================================================== --- lib/Target/AArch64/AArch64Subtarget.h +++ lib/Target/AArch64/AArch64Subtarget.h @@ -41,6 +41,7 @@ bool HasNEON; bool HasCrypto; bool HasCRC; + bool HasV8_1a; // HasZeroCycleRegMove - Has zero-cycle register mov instructions. bool HasZeroCycleRegMove; @@ -100,6 +101,7 @@ bool hasNEON() const { return HasNEON; } bool hasCrypto() const { return HasCrypto; } bool hasCRC() const { return HasCRC; } + bool hasV8_1a() const { return HasV8_1a; } bool isLittleEndian() const { return IsLittle; } Index: lib/Target/AArch64/AArch64Subtarget.cpp =================================================================== --- lib/Target/AArch64/AArch64Subtarget.cpp +++ lib/Target/AArch64/AArch64Subtarget.cpp @@ -48,7 +48,7 @@ const TargetMachine &TM, bool LittleEndian) : AArch64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others), HasFPARMv8(false), HasNEON(false), HasCrypto(false), HasCRC(false), - HasZeroCycleRegMove(false), HasZeroCycleZeroing(false), + HasV8_1a(false), HasZeroCycleRegMove(false), HasZeroCycleZeroing(false), IsLittle(LittleEndian), CPUString(CPU), TargetTriple(TT), FrameLowering(), InstrInfo(initializeSubtargetDependencies(FS)), TSInfo(TM.getDataLayout()), TLInfo(TM, *this) {} Index: lib/Target/AArch64/Utils/AArch64BaseInfo.h =================================================================== --- lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -442,7 +442,8 @@ Invalid = -1, SPSel = 0x05, DAIFSet = 0x1e, - DAIFClr = 0x1f + DAIFClr = 0x1f, + PAN = 0x04, }; struct PStateMapper : AArch64NamedImmMapper { @@ -1130,6 +1131,9 @@ ICH_LR14_EL2 = 0xe66e, // 11 100 1100 1101 110 ICH_LR15_EL2 = 0xe66f, // 11 100 1100 1101 111 + // Privileged Access Never extension specific system registers + PAN = 0xc213, // 11 000 0100 0010 011 + // Cyclone specific system registers CPM_IOACC_CTL_EL3 = 0xff90 }; Index: lib/Target/AArch64/Utils/AArch64BaseInfo.cpp =================================================================== --- lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -140,7 +140,8 @@ const AArch64NamedImmMapper::Mapping AArch64PState::PStateMapper::PStateMappings[] = { {"spsel", SPSel}, {"daifset", DAIFSet}, - {"daifclr", DAIFClr} + {"daifclr", DAIFClr}, + {"pan", PAN, AArch64::FeatureV8_1a}, }; AArch64PState::PStateMapper::PStateMapper(uint64_t SubTargetFeatureBits) @@ -266,7 +267,10 @@ {"icc_dir_el1", ICC_DIR_EL1}, {"icc_sgi1r_el1", ICC_SGI1R_EL1}, {"icc_asgi1r_el1", ICC_ASGI1R_EL1}, - {"icc_sgi0r_el1", ICC_SGI0R_EL1} + {"icc_sgi0r_el1", ICC_SGI0R_EL1}, + + // Privileged Access Never extension specific system registers + {"pan", PAN, AArch64::FeatureV8_1a}, }; AArch64SysReg::MSRMapper::MSRMapper(uint64_t SubTargetFeatureBits) @@ -754,6 +758,9 @@ {"ich_lr14_el2", ICH_LR14_EL2}, {"ich_lr15_el2", ICH_LR15_EL2}, {"cpm_ioacc_ctl_el3", CPM_IOACC_CTL_EL3, AArch64::ProcCyclone}, + + // Privileged Access Never extension specific system registers + {"pan", PAN, AArch64::FeatureV8_1a}, }; uint32_t Index: test/MC/AArch64/armv8-extension-pan.s =================================================================== --- /dev/null +++ test/MC/AArch64/armv8-extension-pan.s @@ -0,0 +1,30 @@ +//RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.1a -show-encoding < %s 2> %t | FileCheck %s +//RUN: FileCheck --check-prefix=CHECK-ERROR %s < %t + + .text + + msr pan, #0 +//CHECK: msr PAN, #0 // encoding: [0x9f,0x40,0x00,0xd5] + msr pan, #1 +//CHECK: msr PAN, #1 // encoding: [0x9f,0x41,0x00,0xd5] + msr pan, x5 +//CHECK: msr PAN, x5 // encoding: [0x65,0x42,0x18,0xd5] + mrs x13, pan +//CHECK: mrs x13, PAN // encoding: [0x6d,0x42,0x38,0xd5] + + msr pan, #-1 + msr pan, #20 + msr pan, w0 + mrs w0, pan +//CHECK-ERROR: error: immediate must be an integer in range [0, 15]. +//CHECK-ERROR: msr pan, #-1 +//CHECK-ERROR: ^ +//CHECK-ERROR: error: immediate must be an integer in range [0, 15]. +//CHECK-ERROR: msr pan, #20 +//CHECK-ERROR: ^ +//CHECK-ERROR: error: immediate must be an integer in range [0, 15]. +//CHECK-ERROR: msr pan, w0 +//CHECK-ERROR: ^ +//CHECK-ERROR: error: invalid operand for instruction +//CHECK-ERROR: mrs w0, pan +//CHECK-ERROR: ^ Index: test/MC/Disassembler/AArch64/armv8-extension-pan.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/AArch64/armv8-extension-pan.txt @@ -0,0 +1,10 @@ +# RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.1a --disassemble < %s | FileCheck %s + +0x9f,0x40,0x00,0xd5 +0x9f,0x41,0x00,0xd5 +0x65,0x42,0x18,0xd5 +0x6d,0x42,0x38,0xd5 +# CHECK: msr PAN, #0 +# CHECK: msr PAN, #1 +# CHECK: msr PAN, x5 +# CHECK: mrs x13, PAN