Index: llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -2266,7 +2266,7 @@ && "Expected a constant integer expression."); uint64_t Immed = cast(N->getOperand(2))->getZExtValue(); unsigned State; - if (Reg == AArch64PState::PAN) { + if (Reg == AArch64PState::PAN || Reg == AArch64PState::UAO) { assert(Immed < 2 && "Bad imm"); State = AArch64::MSRpstateImm1; } else { Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -888,7 +888,8 @@ } bool isSystemPStateFieldWithImm0_1() const { if (!isSysReg()) return false; - return SysReg.PStateField == AArch64PState::PAN; + return (SysReg.PStateField == AArch64PState::PAN || + SysReg.PStateField == AArch64PState::UAO); } bool isSystemPStateFieldWithImm0_15() const { if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false; Index: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -1516,7 +1516,8 @@ uint64_t pstate_field = (op1 << 3) | op2; - if (pstate_field == AArch64PState::PAN && crm > 1) + if ((pstate_field == AArch64PState::PAN || + pstate_field == AArch64PState::UAO) && crm > 1) return Fail; Inst.addOperand(MCOperand::createImm(pstate_field)); Index: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h =================================================================== --- llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -463,6 +463,9 @@ // v8.1a "Privileged Access Never" extension-specific PStates PAN = 0x04, + + // v8.2a "User Access Override" extension-specific PStates + UAO = 0x03 }; struct PStateMapper : AArch64NamedImmMapper { @@ -1191,6 +1194,9 @@ SPSR_EL12 = 0xea00, // 11 101 0100 0000 000 ELR_EL12 = 0xea01, // 11 101 0100 0000 001 + // v8.2a registers + UAO = 0xc214, // 11 000 0100 0010 100 + // Cyclone specific system registers CPM_IOACC_CTL_EL3 = 0xff90, }; Index: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -146,6 +146,9 @@ // v8.1a "Privileged Access Never" extension-specific PStates {"pan", PAN, {AArch64::HasV8_1aOps}}, + + // v8.2a + {"uao", UAO, {AArch64::HasV8_2aOps}}, }; AArch64PState::PStateMapper::PStateMapper() @@ -802,6 +805,9 @@ {"cntv_cval_el02", CNTV_CVAL_EL02, {AArch64::HasV8_1aOps}}, {"spsr_el12", SPSR_EL12, {AArch64::HasV8_1aOps}}, {"elr_el12", ELR_EL12, {AArch64::HasV8_1aOps}}, + + // v8.2a registers + {"uao", UAO, {AArch64::HasV8_2aOps}}, }; uint32_t Index: llvm/trunk/test/MC/AArch64/armv8.2a-uao.s =================================================================== --- llvm/trunk/test/MC/AArch64/armv8.2a-uao.s +++ llvm/trunk/test/MC/AArch64/armv8.2a-uao.s @@ -0,0 +1,17 @@ +// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.2a < %s 2> %t | FileCheck %s +// RUN: FileCheck --check-prefix=CHECK-ERROR %s < %t + + msr uao, #0 + msr uao, #1 +// CHECK: msr UAO, #0 // encoding: [0x7f,0x40,0x00,0xd5] +// CHECK: msr UAO, #1 // encoding: [0x7f,0x41,0x00,0xd5] + + msr uao, #2 +// CHECK-ERROR: error: immediate must be an integer in range [0, 1]. +// CHECK-ERROR: msr uao, #2 +// CHECK-ERROR: ^ + + msr uao, x1 + mrs x2, uao +// CHECK: msr UAO, x1 // encoding: [0x81,0x42,0x18,0xd5] +// CHECK: mrs x2, UAO // encoding: [0x82,0x42,0x38,0xd5] Index: llvm/trunk/test/MC/Disassembler/AArch64/armv8.2a-uao.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/AArch64/armv8.2a-uao.txt +++ llvm/trunk/test/MC/Disassembler/AArch64/armv8.2a-uao.txt @@ -0,0 +1,19 @@ +# RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.2a --disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple aarch64-none-linux-gnu --disassemble < %s 2>&1 | FileCheck --check-prefix=NO_V82A %s + +[0x7f,0x40,0x00,0xd5] +[0x7f,0x41,0x00,0xd5] +[0x7f,0x42,0x00,0xd5] +# CHECK: msr UAO, #0 +# CHECK: msr UAO, #1 +# CHECK: msr S0_0_C4_C2_3, xzr +# NO_V82A: msr S0_0_C4_C0_3, xzr +# NO_V82A: msr S0_0_C4_C1_3, xzr +# NO_V82A: msr S0_0_C4_C2_3, xzr + +[0x81,0x42,0x18,0xd5] +[0x82,0x42,0x38,0xd5] +# CHECK: msr UAO, x1 +# CHECK: mrs x2, UAO +# NO_V82A: msr S3_0_C4_C2_4, x1 +# NO_V82A: mrs x2, S3_0_C4_C2_4