@@ -169,18 +169,22 @@ class AArch64AsmPrinter : public AsmPrinter {
169
169
void emitPtrauthTailCallHardening (const MachineInstr *TC);
170
170
171
171
// 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);
173
178
174
179
// Emit the sequence to compute the discriminator.
175
180
//
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.
179
182
//
180
183
// If the expanded pseudo is allowed to clobber AddrDisc register, setting
181
184
// MayUseAddrAsScratch may save one MOV instruction, provided the address
182
185
// 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()):
184
188
//
185
189
// mov x17, x16
186
190
// movk x17, #1234, lsl #48
@@ -1867,7 +1871,8 @@ Register AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
1867
1871
Register AddrDisc,
1868
1872
Register ScratchReg,
1869
1873
bool MayUseAddrAsScratch) {
1870
- assert (ScratchReg == AArch64::X16 || ScratchReg == AArch64::X17);
1874
+ assert (ScratchReg == AArch64::X16 || ScratchReg == AArch64::X17 ||
1875
+ !STI->isX16X17Safer ());
1871
1876
// So far we've used NoRegister in pseudos. Now we need real encodings.
1872
1877
if (AddrDisc == AArch64::NoRegister)
1873
1878
AddrDisc = AArch64::XZR;
@@ -1887,7 +1892,8 @@ Register AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
1887
1892
1888
1893
// Check if we can save one MOV instruction.
1889
1894
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 ();
1891
1897
if (MayUseAddrAsScratch && AddrDiscIsSafe)
1892
1898
ScratchReg = AddrDisc;
1893
1899
else
@@ -2065,8 +2071,12 @@ void AArch64AsmPrinter::emitPtrauthTailCallHardening(const MachineInstr *TC) {
2065
2071
/* ShouldTrap=*/ true , /* OnFailure=*/ nullptr );
2066
2072
}
2067
2073
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 ();
2070
2080
2071
2081
// We expand AUT/AUTPAC into a sequence of the form
2072
2082
//
@@ -2105,23 +2115,19 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
2105
2115
break ;
2106
2116
}
2107
2117
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
2113
2119
assert (isUInt<16 >(AUTDisc));
2114
- Register AUTDiscReg =
2115
- emitPtrauthDiscriminator ( AUTDisc, AUTAddrDisc, AArch64::X17 );
2120
+ Register AUTDiscReg = emitPtrauthDiscriminator (
2121
+ AUTDisc, AUTAddrDisc-> getReg (), Scratch, AUTAddrDisc-> isKill () );
2116
2122
bool AUTZero = AUTDiscReg == AArch64::XZR;
2117
2123
unsigned AUTOpc = getAUTOpcodeForKey (AUTKey, AUTZero);
2118
2124
2119
2125
// autiza x16 ; if AUTZero
2120
2126
// autia x16, x17 ; if !AUTZero
2121
2127
MCInst AUTInst;
2122
2128
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 ));
2125
2131
if (!AUTZero)
2126
2132
AUTInst.addOperand (MCOperand::createReg (AUTDiscReg));
2127
2133
EmitToStreamer (*OutStreamer, AUTInst);
@@ -2136,7 +2142,7 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
2136
2142
if (IsAUTPAC && !ShouldTrap)
2137
2143
EndSym = createTempSymbol (" resign_end_" );
2138
2144
2139
- emitPtrauthCheckAuthenticatedValue (AArch64::X16, AArch64::X17 , AUTKey,
2145
+ emitPtrauthCheckAuthenticatedValue (AUTVal, Scratch , AUTKey,
2140
2146
AArch64PAuth::AuthCheckMethod::XPAC,
2141
2147
ShouldTrap, EndSym);
2142
2148
}
@@ -2147,23 +2153,19 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
2147
2153
if (!IsAUTPAC)
2148
2154
return ;
2149
2155
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
2155
2157
assert (isUInt<16 >(PACDisc));
2156
2158
Register PACDiscReg =
2157
- emitPtrauthDiscriminator (PACDisc, PACAddrDisc, AArch64::X17 );
2159
+ emitPtrauthDiscriminator (PACDisc, PACAddrDisc, Scratch );
2158
2160
bool PACZero = PACDiscReg == AArch64::XZR;
2159
- unsigned PACOpc = getPACOpcodeForKey (PACKey, PACZero);
2161
+ unsigned PACOpc = getPACOpcodeForKey (* PACKey, PACZero);
2160
2162
2161
2163
// pacizb x16 ; if PACZero
2162
2164
// pacib x16, x17 ; if !PACZero
2163
2165
MCInst PACInst;
2164
2166
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 ));
2167
2169
if (!PACZero)
2168
2170
PACInst.addOperand (MCOperand::createReg (PACDiscReg));
2169
2171
EmitToStreamer (*OutStreamer, PACInst);
@@ -2866,9 +2868,26 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
2866
2868
return ;
2867
2869
}
2868
2870
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
+
2870
2885
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 ());
2872
2891
return ;
2873
2892
2874
2893
case AArch64::LOADauthptrstatic:
0 commit comments