================ @@ -1757,38 +1762,70 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue( // Lsuccess: // ... // - // This sequence is expensive, but we need more information to be able to - // do better. - // - // We can't TBZ the poison bit because EnhancedPAC2 XORs the PAC bits - // on failure. - // We can't TST the PAC bits because we don't always know how the address - // space is setup for the target environment (and the bottom PAC bit is - // based on that). - // Either way, we also don't always know whether TBI is enabled or not for - // the specific target environment. + // See the documentation on AuthCheckMethod enumeration constants for + // the specific code sequences that can be used to perform the check. + using AArch64PAuth::AuthCheckMethod; - unsigned XPACOpc = getXPACOpcodeForKey(Key); + if (Method == AuthCheckMethod::None) + return; + if (Method == AuthCheckMethod::DummyLoad) { + EmitToStreamer(MCInstBuilder(AArch64::LDRWui) + .addReg(getWRegFromXReg(ScratchReg)) + .addReg(TestedReg) + .addImm(0)); + assert(ShouldTrap && !OnFailure && "DummyLoad always traps on error"); + return; + } MCSymbol *SuccessSym = createTempSymbol("auth_success_"); + if (Method == AuthCheckMethod::XPAC || Method == AuthCheckMethod::XPACHint) { + // mov Xscratch, Xtested + emitMovXReg(ScratchReg, TestedReg); - // mov Xscratch, Xtested - emitMovXReg(ScratchReg, TestedReg); - - // xpac(i|d) Xscratch - EmitToStreamer(MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg)); + if (Method == AuthCheckMethod::XPAC) { + // xpac(i|d) Xscratch + unsigned XPACOpc = getXPACOpcodeForKey(Key); + EmitToStreamer( + MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg)); + } else { + // xpaclri + + // Note that this method applies XPAC to TestedReg instead of ScratchReg. + assert(TestedReg == AArch64::LR && + "XPACHint mode is only compatible with checking the LR register"); + assert((Key == AArch64PACKey::IA || Key == AArch64PACKey::IB) && + "XPACHint mode is only compatible with I-keys"); + EmitToStreamer(MCInstBuilder(AArch64::XPACLRI)); + } - // cmp Xtested, Xscratch - EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs) - .addReg(AArch64::XZR) - .addReg(TestedReg) - .addReg(ScratchReg) - .addImm(0)); + // cmp Xtested, Xscratch + EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs) + .addReg(AArch64::XZR) + .addReg(TestedReg) + .addReg(ScratchReg) + .addImm(0)); - // b.eq Lsuccess - EmitToStreamer(MCInstBuilder(AArch64::Bcc) - .addImm(AArch64CC::EQ) - .addExpr(MCSymbolRefExpr::create(SuccessSym, OutContext))); + // b.eq Lsuccess + EmitToStreamer( + MCInstBuilder(AArch64::Bcc) + .addImm(AArch64CC::EQ) + .addExpr(MCSymbolRefExpr::create(SuccessSym, OutContext))); + } else if (Method == AuthCheckMethod::HighBitsNoTBI) { + // eor Xscratch, Xtested, Xtested, lsl #1 + EmitToStreamer(MCInstBuilder(AArch64::EORXrs) + .addReg(ScratchReg) + .addReg(TestedReg) + .addReg(TestedReg) + .addImm(1)); + // tbz Xscratch, #62, Lsuccess + EmitToStreamer( + MCInstBuilder(AArch64::TBZX) + .addReg(ScratchReg) + .addImm(62) + .addExpr(MCSymbolRefExpr::create(SuccessSym, OutContext))); + } else { ---------------- kovdan01 wrote:
Nit: alternatively, you can change the previous `else if` to just `else` and put `Method == AuthCheckMethod::HighBitsNoTBI` condition as an assert in its beginning. Feel free to ignore. https://github.com/llvm/llvm-project/pull/110705 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits