@@ -219,6 +219,10 @@ class AArch64AsmPrinter : public AsmPrinter {
219219 // authenticating)
220220 void LowerLOADgotAUTH (const MachineInstr &MI);
221221
222+ void emitAddImm (MCRegister Val, int64_t Addend, MCRegister Tmp);
223+ void emitAddress (MCRegister Reg, const MCExpr *Expr, MCRegister Tmp,
224+ bool DSOLocal, const MCSubtargetInfo &STI);
225+
222226 const MCExpr *emitPAuthRelocationAsIRelative (
223227 const MCExpr *Target, uint64_t Disc, AArch64PACKey::ID KeyID,
224228 bool HasAddressDiversity, bool IsDSOLocal, const MCExpr *DSExpr);
@@ -2336,50 +2340,82 @@ void AArch64AsmPrinter::emitPtrauthBranch(const MachineInstr *MI) {
23362340 EmitToStreamer (*OutStreamer, BRInst);
23372341}
23382342
2339- static void emitAddress (MCStreamer &Streamer, MCRegister Reg,
2340- const MCExpr *Expr, bool DSOLocal,
2341- const MCSubtargetInfo &STI) {
2343+ void AArch64AsmPrinter::emitAddImm (MCRegister Reg, int64_t Addend,
2344+ MCRegister Tmp) {
2345+ if (Addend != 0 ) {
2346+ const uint64_t AbsOffset = (Addend > 0 ? Addend : -((uint64_t )Addend));
2347+ const bool IsNeg = Addend < 0 ;
2348+ if (isUInt<24 >(AbsOffset)) {
2349+ for (int BitPos = 0 ; BitPos != 24 && (AbsOffset >> BitPos);
2350+ BitPos += 12 ) {
2351+ EmitToStreamer (
2352+ MCInstBuilder (IsNeg ? AArch64::SUBXri : AArch64::ADDXri)
2353+ .addReg (Reg)
2354+ .addReg (Reg)
2355+ .addImm ((AbsOffset >> BitPos) & 0xfff )
2356+ .addImm (AArch64_AM::getShifterImm (AArch64_AM::LSL, BitPos)));
2357+ }
2358+ } else {
2359+ const uint64_t UAddend = Addend;
2360+ EmitToStreamer (MCInstBuilder (IsNeg ? AArch64::MOVNXi : AArch64::MOVZXi)
2361+ .addReg (Tmp)
2362+ .addImm ((IsNeg ? ~UAddend : UAddend) & 0xffff )
2363+ .addImm (/* shift=*/ 0 ));
2364+ auto NeedMovk = [IsNeg, UAddend](int BitPos) -> bool {
2365+ assert (BitPos == 16 || BitPos == 32 || BitPos == 48 );
2366+ uint64_t Shifted = UAddend >> BitPos;
2367+ if (!IsNeg)
2368+ return Shifted != 0 ;
2369+ for (int I = 0 ; I != 64 - BitPos; I += 16 )
2370+ if (((Shifted >> I) & 0xffff ) != 0xffff )
2371+ return true ;
2372+ return false ;
2373+ };
2374+ for (int BitPos = 16 ; BitPos != 64 && NeedMovk (BitPos); BitPos += 16 )
2375+ emitMOVK (Tmp, (UAddend >> BitPos) & 0xffff , BitPos);
2376+
2377+ EmitToStreamer (MCInstBuilder (AArch64::ADDXrs)
2378+ .addReg (Reg)
2379+ .addReg (Reg)
2380+ .addReg (Tmp)
2381+ .addImm (/* shift=*/ 0 ));
2382+ }
2383+ }
2384+ }
2385+
2386+ void AArch64AsmPrinter::emitAddress (MCRegister Reg, const MCExpr *Expr,
2387+ MCRegister Tmp, bool DSOLocal,
2388+ const MCSubtargetInfo &STI) {
23422389 MCValue Val;
23432390 if (!Expr->evaluateAsRelocatable (Val, nullptr ))
23442391 report_fatal_error (" emitAddress could not evaluate" );
23452392 if (DSOLocal) {
2346- Streamer. emitInstruction (
2393+ EmitToStreamer (
23472394 MCInstBuilder (AArch64::ADRP)
23482395 .addReg (Reg)
23492396 .addExpr (MCSpecifierExpr::create (Expr, AArch64::S_ABS_PAGE,
2350- Streamer.getContext ())),
2351- STI);
2352- Streamer.emitInstruction (
2353- MCInstBuilder (AArch64::ADDXri)
2354- .addReg (Reg)
2355- .addReg (Reg)
2356- .addExpr (MCSpecifierExpr::create (Expr, AArch64::S_LO12,
2357- Streamer.getContext ()))
2358- .addImm (0 ),
2359- STI);
2397+ OutStreamer->getContext ())));
2398+ EmitToStreamer (MCInstBuilder (AArch64::ADDXri)
2399+ .addReg (Reg)
2400+ .addReg (Reg)
2401+ .addExpr (MCSpecifierExpr::create (
2402+ Expr, AArch64::S_LO12, OutStreamer->getContext ()))
2403+ .addImm (0 ));
23602404 } else {
23612405 auto *SymRef =
2362- MCSymbolRefExpr::create (Val.getAddSym (), Streamer. getContext ());
2363- Streamer. emitInstruction (
2406+ MCSymbolRefExpr::create (Val.getAddSym (), OutStreamer-> getContext ());
2407+ EmitToStreamer (
23642408 MCInstBuilder (AArch64::ADRP)
23652409 .addReg (Reg)
23662410 .addExpr (MCSpecifierExpr::create (SymRef, AArch64::S_GOT_PAGE,
2367- Streamer.getContext ())),
2368- STI);
2369- Streamer.emitInstruction (
2411+ OutStreamer->getContext ())));
2412+ EmitToStreamer (
23702413 MCInstBuilder (AArch64::LDRXui)
23712414 .addReg (Reg)
23722415 .addReg (Reg)
23732416 .addExpr (MCSpecifierExpr::create (SymRef, AArch64::S_GOT_LO12,
2374- Streamer.getContext ())),
2375- STI);
2376- if (Val.getConstant ())
2377- Streamer.emitInstruction (MCInstBuilder (AArch64::ADDXri)
2378- .addReg (Reg)
2379- .addReg (Reg)
2380- .addImm (Val.getConstant ())
2381- .addImm (0 ),
2382- STI);
2417+ OutStreamer->getContext ())));
2418+ emitAddImm (Reg, Val.getConstant (), Tmp);
23832419 }
23842420}
23852421
@@ -2504,14 +2540,14 @@ const MCExpr *AArch64AsmPrinter::emitPAuthRelocationAsIRelative(
25042540 .addImm (0 ),
25052541 *STI);
25062542 } else {
2507- emitAddress (*OutStreamer, AArch64::X0, Target, IsDSOLocal, *STI);
2543+ emitAddress (AArch64::X0, Target, AArch64::X16 , IsDSOLocal, *STI);
25082544 }
25092545 if (HasAddressDiversity) {
25102546 auto *PlacePlusDisc = MCBinaryExpr::createAdd (
25112547 MCSymbolRefExpr::create (Place, OutStreamer->getContext ()),
25122548 MCConstantExpr::create (Disc, OutStreamer->getContext ()),
25132549 OutStreamer->getContext ());
2514- emitAddress (*OutStreamer, AArch64::X1, PlacePlusDisc, /* IsDSOLocal=*/ true ,
2550+ emitAddress (AArch64::X1, PlacePlusDisc, AArch64::X16 , /* IsDSOLocal=*/ true ,
25152551 *STI);
25162552 } else {
25172553 if (!isUInt<16 >(Disc)) {
@@ -2801,46 +2837,7 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
28012837 .addImm (0 ));
28022838 }
28032839
2804- if (Offset != 0 ) {
2805- const uint64_t AbsOffset = (Offset > 0 ? Offset : -((uint64_t )Offset));
2806- const bool IsNeg = Offset < 0 ;
2807- if (isUInt<24 >(AbsOffset)) {
2808- for (int BitPos = 0 ; BitPos != 24 && (AbsOffset >> BitPos);
2809- BitPos += 12 ) {
2810- EmitToStreamer (
2811- MCInstBuilder (IsNeg ? AArch64::SUBXri : AArch64::ADDXri)
2812- .addReg (AArch64::X16)
2813- .addReg (AArch64::X16)
2814- .addImm ((AbsOffset >> BitPos) & 0xfff )
2815- .addImm (AArch64_AM::getShifterImm (AArch64_AM::LSL, BitPos)));
2816- }
2817- } else {
2818- const uint64_t UOffset = Offset;
2819- EmitToStreamer (MCInstBuilder (IsNeg ? AArch64::MOVNXi : AArch64::MOVZXi)
2820- .addReg (AArch64::X17)
2821- .addImm ((IsNeg ? ~UOffset : UOffset) & 0xffff )
2822- .addImm (/* shift=*/ 0 ));
2823- auto NeedMovk = [IsNeg, UOffset](int BitPos) -> bool {
2824- assert (BitPos == 16 || BitPos == 32 || BitPos == 48 );
2825- uint64_t Shifted = UOffset >> BitPos;
2826- if (!IsNeg)
2827- return Shifted != 0 ;
2828- for (int I = 0 ; I != 64 - BitPos; I += 16 )
2829- if (((Shifted >> I) & 0xffff ) != 0xffff )
2830- return true ;
2831- return false ;
2832- };
2833- for (int BitPos = 16 ; BitPos != 64 && NeedMovk (BitPos); BitPos += 16 )
2834- emitMOVK (AArch64::X17, (UOffset >> BitPos) & 0xffff , BitPos);
2835-
2836- EmitToStreamer (MCInstBuilder (AArch64::ADDXrs)
2837- .addReg (AArch64::X16)
2838- .addReg (AArch64::X16)
2839- .addReg (AArch64::X17)
2840- .addImm (/* shift=*/ 0 ));
2841- }
2842- }
2843-
2840+ emitAddImm (AArch64::X16, Offset, AArch64::X17);
28442841 Register DiscReg = emitPtrauthDiscriminator (Disc, AddrDisc, AArch64::X17);
28452842
28462843 auto MIB = MCInstBuilder (getPACOpcodeForKey (Key, DiscReg == AArch64::XZR))
0 commit comments