@@ -169,18 +169,22 @@ class AArch64AsmPrinter : public AsmPrinter {
169169 void emitPtrauthTailCallHardening (const MachineInstr *TC);
170170
171171 // Emit the sequence for AUT or AUTPAC.
172- void emitPtrauthAuthResign (const MachineInstr *MI);
172+ void emitPtrauthAuthResign (Register AUTVal, AArch64PACKey::ID AUTKey,
173+ uint64_t AUTDisc,
174+ const MachineOperand *AUTAddrDisc,
175+ Register Scratch,
176+ std::optional<AArch64PACKey::ID> PACKey,
177+ uint64_t PACDisc, Register PACAddrDisc);
173178
174179 // Emit the sequence to compute the discriminator.
175180 //
176- // ScratchReg should be x16/x17.
177- //
178- // The returned register is either unmodified AddrDisc or x16/x17.
181+ // The returned register is either unmodified AddrDisc or ScratchReg.
179182 //
180183 // If the expanded pseudo is allowed to clobber AddrDisc register, setting
181184 // MayUseAddrAsScratch may save one MOV instruction, provided the address
182185 // is already in x16/x17 (i.e. return x16/x17 which is the *modified* AddrDisc
183- // register at the same time):
186+ // register at the same time) or the OS doesn't make it safer to use x16/x17
187+ // (see AArch64Subtarget::isX16X17Safer()):
184188 //
185189 // mov x17, x16
186190 // movk x17, #1234, lsl #48
@@ -1867,7 +1871,8 @@ Register AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
18671871 Register AddrDisc,
18681872 Register ScratchReg,
18691873 bool MayUseAddrAsScratch) {
1870- assert (ScratchReg == AArch64::X16 || ScratchReg == AArch64::X17);
1874+ assert (ScratchReg == AArch64::X16 || ScratchReg == AArch64::X17 ||
1875+ !STI->isX16X17Safer ());
18711876 // So far we've used NoRegister in pseudos. Now we need real encodings.
18721877 if (AddrDisc == AArch64::NoRegister)
18731878 AddrDisc = AArch64::XZR;
@@ -1887,7 +1892,8 @@ Register AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
18871892
18881893 // Check if we can save one MOV instruction.
18891894 assert (MayUseAddrAsScratch || ScratchReg != AddrDisc);
1890- bool AddrDiscIsSafe = AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17;
1895+ bool AddrDiscIsSafe = AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17 ||
1896+ !STI->isX16X17Safer ();
18911897 if (MayUseAddrAsScratch && AddrDiscIsSafe)
18921898 ScratchReg = AddrDisc;
18931899 else
@@ -2065,8 +2071,12 @@ void AArch64AsmPrinter::emitPtrauthTailCallHardening(const MachineInstr *TC) {
20652071 /* ShouldTrap=*/ true , /* OnFailure=*/ nullptr );
20662072}
20672073
2068- void AArch64AsmPrinter::emitPtrauthAuthResign (const MachineInstr *MI) {
2069- const bool IsAUTPAC = MI->getOpcode () == AArch64::AUTPAC;
2074+ void AArch64AsmPrinter::emitPtrauthAuthResign (
2075+ Register AUTVal, AArch64PACKey::ID AUTKey, uint64_t AUTDisc,
2076+ const MachineOperand *AUTAddrDisc, Register Scratch,
2077+ std::optional<AArch64PACKey::ID> PACKey, uint64_t PACDisc,
2078+ Register PACAddrDisc) {
2079+ const bool IsAUTPAC = PACKey.has_value ();
20702080
20712081 // We expand AUT/AUTPAC into a sequence of the form
20722082 //
@@ -2105,23 +2115,19 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
21052115 break ;
21062116 }
21072117
2108- auto AUTKey = (AArch64PACKey::ID)MI->getOperand (0 ).getImm ();
2109- uint64_t AUTDisc = MI->getOperand (1 ).getImm ();
2110- unsigned AUTAddrDisc = MI->getOperand (2 ).getReg ();
2111-
2112- // Compute aut discriminator into x17
2118+ // Compute aut discriminator
21132119 assert (isUInt<16 >(AUTDisc));
2114- Register AUTDiscReg =
2115- emitPtrauthDiscriminator ( AUTDisc, AUTAddrDisc, AArch64::X17 );
2120+ Register AUTDiscReg = emitPtrauthDiscriminator (
2121+ AUTDisc, AUTAddrDisc-> getReg (), Scratch, AUTAddrDisc-> isKill () );
21162122 bool AUTZero = AUTDiscReg == AArch64::XZR;
21172123 unsigned AUTOpc = getAUTOpcodeForKey (AUTKey, AUTZero);
21182124
21192125 // autiza x16 ; if AUTZero
21202126 // autia x16, x17 ; if !AUTZero
21212127 MCInst AUTInst;
21222128 AUTInst.setOpcode (AUTOpc);
2123- AUTInst.addOperand (MCOperand::createReg (AArch64::X16 ));
2124- AUTInst.addOperand (MCOperand::createReg (AArch64::X16 ));
2129+ AUTInst.addOperand (MCOperand::createReg (AUTVal ));
2130+ AUTInst.addOperand (MCOperand::createReg (AUTVal ));
21252131 if (!AUTZero)
21262132 AUTInst.addOperand (MCOperand::createReg (AUTDiscReg));
21272133 EmitToStreamer (*OutStreamer, AUTInst);
@@ -2136,7 +2142,7 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
21362142 if (IsAUTPAC && !ShouldTrap)
21372143 EndSym = createTempSymbol (" resign_end_" );
21382144
2139- emitPtrauthCheckAuthenticatedValue (AArch64::X16, AArch64::X17 , AUTKey,
2145+ emitPtrauthCheckAuthenticatedValue (AUTVal, Scratch , AUTKey,
21402146 AArch64PAuth::AuthCheckMethod::XPAC,
21412147 ShouldTrap, EndSym);
21422148 }
@@ -2147,23 +2153,19 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
21472153 if (!IsAUTPAC)
21482154 return ;
21492155
2150- auto PACKey = (AArch64PACKey::ID)MI->getOperand (3 ).getImm ();
2151- uint64_t PACDisc = MI->getOperand (4 ).getImm ();
2152- unsigned PACAddrDisc = MI->getOperand (5 ).getReg ();
2153-
2154- // Compute pac discriminator into x17
2156+ // Compute pac discriminator
21552157 assert (isUInt<16 >(PACDisc));
21562158 Register PACDiscReg =
2157- emitPtrauthDiscriminator (PACDisc, PACAddrDisc, AArch64::X17 );
2159+ emitPtrauthDiscriminator (PACDisc, PACAddrDisc, Scratch );
21582160 bool PACZero = PACDiscReg == AArch64::XZR;
2159- unsigned PACOpc = getPACOpcodeForKey (PACKey, PACZero);
2161+ unsigned PACOpc = getPACOpcodeForKey (* PACKey, PACZero);
21602162
21612163 // pacizb x16 ; if PACZero
21622164 // pacib x16, x17 ; if !PACZero
21632165 MCInst PACInst;
21642166 PACInst.setOpcode (PACOpc);
2165- PACInst.addOperand (MCOperand::createReg (AArch64::X16 ));
2166- PACInst.addOperand (MCOperand::createReg (AArch64::X16 ));
2167+ PACInst.addOperand (MCOperand::createReg (AUTVal ));
2168+ PACInst.addOperand (MCOperand::createReg (AUTVal ));
21672169 if (!PACZero)
21682170 PACInst.addOperand (MCOperand::createReg (PACDiscReg));
21692171 EmitToStreamer (*OutStreamer, PACInst);
@@ -2866,9 +2868,26 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
28662868 return ;
28672869 }
28682870
2869- case AArch64::AUT:
2871+ case AArch64::AUTx16x17:
2872+ emitPtrauthAuthResign (AArch64::X16,
2873+ (AArch64PACKey::ID)MI->getOperand (0 ).getImm (),
2874+ MI->getOperand (1 ).getImm (), &MI->getOperand (2 ),
2875+ AArch64::X17, std::nullopt , 0 , 0 );
2876+ return ;
2877+
2878+ case AArch64::AUTxMxN:
2879+ emitPtrauthAuthResign (MI->getOperand (0 ).getReg (),
2880+ (AArch64PACKey::ID)MI->getOperand (3 ).getImm (),
2881+ MI->getOperand (4 ).getImm (), &MI->getOperand (5 ),
2882+ MI->getOperand (1 ).getReg (), std::nullopt , 0 , 0 );
2883+ return ;
2884+
28702885 case AArch64::AUTPAC:
2871- emitPtrauthAuthResign (MI);
2886+ emitPtrauthAuthResign (
2887+ AArch64::X16, (AArch64PACKey::ID)MI->getOperand (0 ).getImm (),
2888+ MI->getOperand (1 ).getImm (), &MI->getOperand (2 ), AArch64::X17,
2889+ (AArch64PACKey::ID)MI->getOperand (3 ).getImm (),
2890+ MI->getOperand (4 ).getImm (), MI->getOperand (5 ).getReg ());
28722891 return ;
28732892
28742893 case AArch64::LOADauthptrstatic:
0 commit comments