@@ -313,6 +313,11 @@ class AArch64AsmPrinter : public AsmPrinter {
313313 void emitMOVZ (Register Dest, uint64_t Imm, unsigned Shift);
314314 void emitMOVK (Register Dest, uint64_t Imm, unsigned Shift);
315315
316+ void emitAUT (AArch64PACKey::ID Key, Register Pointer, Register Disc);
317+ void emitPAC (AArch64PACKey::ID Key, Register Pointer, Register Disc);
318+ void emitBLRA (bool IsCall, AArch64PACKey::ID Key, Register Target,
319+ Register Disc);
320+
316321 // / Emit instruction to set float register to zero.
317322 void emitFMov0 (const MachineInstr &MI);
318323 void emitFMov0AsFMov (const MachineInstr &MI, Register DestReg);
@@ -1834,6 +1839,55 @@ void AArch64AsmPrinter::emitMOVK(Register Dest, uint64_t Imm, unsigned Shift) {
18341839 .addImm (Shift));
18351840}
18361841
1842+ void AArch64AsmPrinter::emitAUT (AArch64PACKey::ID Key, Register Pointer,
1843+ Register Disc) {
1844+ bool IsZeroDisc = Disc == AArch64::XZR;
1845+ unsigned Opcode = getAUTOpcodeForKey (Key, IsZeroDisc);
1846+
1847+ // autiza x16 ; if IsZeroDisc
1848+ // autia x16, x17 ; if !IsZeroDisc
1849+ MCInst AUTInst;
1850+ AUTInst.setOpcode (Opcode);
1851+ AUTInst.addOperand (MCOperand::createReg (Pointer));
1852+ AUTInst.addOperand (MCOperand::createReg (Pointer));
1853+ if (!IsZeroDisc)
1854+ AUTInst.addOperand (MCOperand::createReg (Disc));
1855+
1856+ EmitToStreamer (AUTInst);
1857+ }
1858+
1859+ void AArch64AsmPrinter::emitPAC (AArch64PACKey::ID Key, Register Pointer,
1860+ Register Disc) {
1861+ bool IsZeroDisc = Disc == AArch64::XZR;
1862+ unsigned Opcode = getPACOpcodeForKey (Key, IsZeroDisc);
1863+
1864+ // paciza x16 ; if IsZeroDisc
1865+ // pacia x16, x17 ; if !IsZeroDisc
1866+ MCInst PACInst;
1867+ PACInst.setOpcode (Opcode);
1868+ PACInst.addOperand (MCOperand::createReg (Pointer));
1869+ PACInst.addOperand (MCOperand::createReg (Pointer));
1870+ if (!IsZeroDisc)
1871+ PACInst.addOperand (MCOperand::createReg (Disc));
1872+
1873+ EmitToStreamer (PACInst);
1874+ }
1875+
1876+ void AArch64AsmPrinter::emitBLRA (bool IsCall, AArch64PACKey::ID Key,
1877+ Register Target, Register Disc) {
1878+ bool IsZeroDisc = Disc == AArch64::XZR;
1879+ unsigned Opcode = getBranchOpcodeForKey (IsCall, Key, IsZeroDisc);
1880+
1881+ // blraaz x16 ; if IsZeroDisc
1882+ // blraa x16, x17 ; if !IsZeroDisc
1883+ MCInst Inst;
1884+ Inst.setOpcode (Opcode);
1885+ Inst.addOperand (MCOperand::createReg (Target));
1886+ if (!IsZeroDisc)
1887+ Inst.addOperand (MCOperand::createReg (Disc));
1888+ EmitToStreamer (Inst);
1889+ }
1890+
18371891void AArch64AsmPrinter::emitFMov0 (const MachineInstr &MI) {
18381892 Register DestReg = MI.getOperand (0 ).getReg ();
18391893 if (!STI->hasZeroCycleZeroingFPWorkaround () && STI->isNeonAvailable ()) {
@@ -2162,18 +2216,7 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(
21622216 // Compute aut discriminator
21632217 Register AUTDiscReg = emitPtrauthDiscriminator (
21642218 AUTDisc, AUTAddrDisc->getReg (), Scratch, AUTAddrDisc->isKill ());
2165- bool AUTZero = AUTDiscReg == AArch64::XZR;
2166- unsigned AUTOpc = getAUTOpcodeForKey (AUTKey, AUTZero);
2167-
2168- // autiza x16 ; if AUTZero
2169- // autia x16, x17 ; if !AUTZero
2170- MCInst AUTInst;
2171- AUTInst.setOpcode (AUTOpc);
2172- AUTInst.addOperand (MCOperand::createReg (AUTVal));
2173- AUTInst.addOperand (MCOperand::createReg (AUTVal));
2174- if (!AUTZero)
2175- AUTInst.addOperand (MCOperand::createReg (AUTDiscReg));
2176- EmitToStreamer (*OutStreamer, AUTInst);
2219+ emitAUT (AUTKey, AUTVal, AUTDiscReg);
21772220
21782221 // Unchecked or checked-but-non-trapping AUT is just an "AUT": we're done.
21792222 if (!IsAUTPAC && (!ShouldCheck || !ShouldTrap))
@@ -2196,20 +2239,8 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(
21962239 return ;
21972240
21982241 // Compute pac discriminator
2199- Register PACDiscReg =
2200- emitPtrauthDiscriminator (PACDisc, PACAddrDisc, Scratch);
2201- bool PACZero = PACDiscReg == AArch64::XZR;
2202- unsigned PACOpc = getPACOpcodeForKey (*PACKey, PACZero);
2203-
2204- // pacizb x16 ; if PACZero
2205- // pacib x16, x17 ; if !PACZero
2206- MCInst PACInst;
2207- PACInst.setOpcode (PACOpc);
2208- PACInst.addOperand (MCOperand::createReg (AUTVal));
2209- PACInst.addOperand (MCOperand::createReg (AUTVal));
2210- if (!PACZero)
2211- PACInst.addOperand (MCOperand::createReg (PACDiscReg));
2212- EmitToStreamer (*OutStreamer, PACInst);
2242+ Register PACDiscReg = emitPtrauthDiscriminator (PACDisc, PACAddrDisc, Scratch);
2243+ emitPAC (*PACKey, AUTVal, PACDiscReg);
22132244
22142245 // Lend:
22152246 if (EndSym)
@@ -2232,28 +2263,14 @@ void AArch64AsmPrinter::emitPtrauthSign(const MachineInstr *MI) {
22322263 // Compute pac discriminator
22332264 Register DiscReg = emitPtrauthDiscriminator (
22342265 Disc, AddrDisc, ScratchReg, /* MayUseAddrAsScratch=*/ AddrDiscKilled);
2235- bool IsZeroDisc = DiscReg == AArch64::XZR;
2236- unsigned Opc = getPACOpcodeForKey (Key, IsZeroDisc);
2237-
2238- // paciza x16 ; if IsZeroDisc
2239- // pacia x16, x17 ; if !IsZeroDisc
2240- MCInst PACInst;
2241- PACInst.setOpcode (Opc);
2242- PACInst.addOperand (MCOperand::createReg (Val));
2243- PACInst.addOperand (MCOperand::createReg (Val));
2244- if (!IsZeroDisc)
2245- PACInst.addOperand (MCOperand::createReg (DiscReg));
2246- EmitToStreamer (*OutStreamer, PACInst);
2266+ emitPAC (Key, Val, DiscReg);
22472267}
22482268
22492269void AArch64AsmPrinter::emitPtrauthBranch (const MachineInstr *MI) {
22502270 bool IsCall = MI->getOpcode () == AArch64::BLRA;
22512271 unsigned BrTarget = MI->getOperand (0 ).getReg ();
22522272
22532273 auto Key = (AArch64PACKey::ID)MI->getOperand (1 ).getImm ();
2254- assert ((Key == AArch64PACKey::IA || Key == AArch64PACKey::IB) &&
2255- " Invalid auth call key" );
2256-
22572274 uint64_t Disc = MI->getOperand (2 ).getImm ();
22582275
22592276 unsigned AddrDisc = MI->getOperand (3 ).getReg ();
@@ -2283,27 +2300,7 @@ void AArch64AsmPrinter::emitPtrauthBranch(const MachineInstr *MI) {
22832300 IsCall && (AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17);
22842301 Register DiscReg = emitPtrauthDiscriminator (Disc, AddrDisc, AArch64::X17,
22852302 AddrDiscIsImplicitDef);
2286- bool IsZeroDisc = DiscReg == AArch64::XZR;
2287-
2288- unsigned Opc;
2289- if (IsCall) {
2290- if (Key == AArch64PACKey::IA)
2291- Opc = IsZeroDisc ? AArch64::BLRAAZ : AArch64::BLRAA;
2292- else
2293- Opc = IsZeroDisc ? AArch64::BLRABZ : AArch64::BLRAB;
2294- } else {
2295- if (Key == AArch64PACKey::IA)
2296- Opc = IsZeroDisc ? AArch64::BRAAZ : AArch64::BRAA;
2297- else
2298- Opc = IsZeroDisc ? AArch64::BRABZ : AArch64::BRAB;
2299- }
2300-
2301- MCInst BRInst;
2302- BRInst.setOpcode (Opc);
2303- BRInst.addOperand (MCOperand::createReg (BrTarget));
2304- if (!IsZeroDisc)
2305- BRInst.addOperand (MCOperand::createReg (DiscReg));
2306- EmitToStreamer (*OutStreamer, BRInst);
2303+ emitBLRA (IsCall, Key, BrTarget, DiscReg);
23072304}
23082305
23092306const MCExpr *
@@ -2506,22 +2503,14 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
25062503
25072504 assert (GAOp.isGlobal ());
25082505 assert (GAOp.getGlobal ()->getValueType () != nullptr );
2509- unsigned AuthOpcode = GAOp.getGlobal ()->getValueType ()->isFunctionTy ()
2510- ? AArch64::AUTIA
2511- : AArch64::AUTDA;
2512-
2513- EmitToStreamer (MCInstBuilder (AuthOpcode)
2514- .addReg (AArch64::X16)
2515- .addReg (AArch64::X16)
2516- .addReg (AArch64::X17));
25172506
2518- if (!STI-> hasFPAC ()) {
2519- auto AuthKey = (AuthOpcode == AArch64::AUTIA ? AArch64PACKey::IA
2520- : AArch64PACKey::DA );
2507+ bool IsFunctionTy = GAOp. getGlobal ()-> getValueType ()-> isFunctionTy ();
2508+ auto AuthKey = IsFunctionTy ? AArch64PACKey::IA : AArch64PACKey::DA;
2509+ emitAUT (AuthKey, AArch64::X16, AArch64::X17 );
25212510
2511+ if (!STI->hasFPAC ())
25222512 emitPtrauthCheckAuthenticatedValue (AArch64::X16, AArch64::X17, AuthKey,
25232513 AArch64PAuth::AuthCheckMethod::XPAC);
2524- }
25252514 } else {
25262515 EmitToStreamer (MCInstBuilder (AArch64::LDRXui)
25272516 .addReg (AArch64::X16)
@@ -2578,12 +2567,7 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
25782567
25792568 Register DiscReg = emitPtrauthDiscriminator (Disc, AddrDisc, AArch64::X17);
25802569
2581- auto MIB = MCInstBuilder (getPACOpcodeForKey (Key, DiscReg == AArch64::XZR))
2582- .addReg (AArch64::X16)
2583- .addReg (AArch64::X16);
2584- if (DiscReg != AArch64::XZR)
2585- MIB.addReg (DiscReg);
2586- EmitToStreamer (MIB);
2570+ emitPAC (Key, AArch64::X16, DiscReg);
25872571}
25882572
25892573void AArch64AsmPrinter::LowerLOADgotAUTH (const MachineInstr &MI) {
@@ -2637,21 +2621,15 @@ void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) {
26372621 }
26382622
26392623 assert (GAMO.getGlobal ()->getValueType () != nullptr );
2640- unsigned AuthOpcode = GAMO.getGlobal ()->getValueType ()->isFunctionTy ()
2641- ? AArch64::AUTIA
2642- : AArch64::AUTDA;
2643- EmitToStreamer (MCInstBuilder (AuthOpcode)
2644- .addReg (AuthResultReg)
2645- .addReg (AuthResultReg)
2646- .addReg (AArch64::X17));
2624+
2625+ bool IsFunctionTy = GAMO.getGlobal ()->getValueType ()->isFunctionTy ();
2626+ auto AuthKey = IsFunctionTy ? AArch64PACKey::IA : AArch64PACKey::DA;
2627+ emitAUT (AuthKey, AuthResultReg, AArch64::X17);
26472628
26482629 if (GAMO.getGlobal ()->hasExternalWeakLinkage ())
26492630 OutStreamer->emitLabel (UndefWeakSym);
26502631
26512632 if (!STI->hasFPAC ()) {
2652- auto AuthKey =
2653- (AuthOpcode == AArch64::AUTIA ? AArch64PACKey::IA : AArch64PACKey::DA);
2654-
26552633 emitPtrauthCheckAuthenticatedValue (AuthResultReg, AArch64::X17, AuthKey,
26562634 AArch64PAuth::AuthCheckMethod::XPAC);
26572635
@@ -3002,10 +2980,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
30022980 case AArch64::AUTH_TCRETURN:
30032981 case AArch64::AUTH_TCRETURN_BTI: {
30042982 Register Callee = MI->getOperand (0 ).getReg ();
3005- const uint64_t Key = MI->getOperand (2 ).getImm ();
3006- assert ((Key == AArch64PACKey::IA || Key == AArch64PACKey::IB) &&
3007- " Invalid auth key for tail-call return" );
3008-
2983+ const auto Key = (AArch64PACKey::ID)MI->getOperand (2 ).getImm ();
30092984 const uint64_t Disc = MI->getOperand (3 ).getImm ();
30102985
30112986 Register AddrDisc = MI->getOperand (4 ).getReg ();
@@ -3026,17 +3001,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
30263001 AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17;
30273002 Register DiscReg = emitPtrauthDiscriminator (Disc, AddrDisc, ScratchReg,
30283003 AddrDiscIsImplicitDef);
3029-
3030- const bool IsZero = DiscReg == AArch64::XZR;
3031- const unsigned Opcodes[2 ][2 ] = {{AArch64::BRAA, AArch64::BRAAZ},
3032- {AArch64::BRAB, AArch64::BRABZ}};
3033-
3034- MCInst TmpInst;
3035- TmpInst.setOpcode (Opcodes[Key][IsZero]);
3036- TmpInst.addOperand (MCOperand::createReg (Callee));
3037- if (!IsZero)
3038- TmpInst.addOperand (MCOperand::createReg (DiscReg));
3039- EmitToStreamer (*OutStreamer, TmpInst);
3004+ emitBLRA (/* IsCall*/ false , Key, Callee, DiscReg);
30403005 return ;
30413006 }
30423007
0 commit comments