@@ -164,6 +164,8 @@ class AArch64AsmPrinter : public AsmPrinter {
164164 // / pseudo instructions.
165165 bool lowerPseudoInstExpansion (const MachineInstr *MI, MCInst &Inst);
166166
167+ void EmitToStreamer (MCStreamer &S, const MCInst &Inst);
168+
167169 void emitInstruction (const MachineInstr *MI) override ;
168170
169171 void emitFunctionHeaderComment () override ;
@@ -229,6 +231,10 @@ class AArch64AsmPrinter : public AsmPrinter {
229231 // / Emit the LOHs contained in AArch64FI.
230232 void emitLOHs ();
231233
234+ void emitMovXReg (Register Dest, Register Src);
235+ void emitMOVZ (Register Dest, uint64_t Imm, unsigned Shift);
236+ void emitMOVK (Register Dest, uint64_t Imm, unsigned Shift);
237+
232238 // / Emit instruction to set float register to zero.
233239 void emitFMov0 (const MachineInstr &MI);
234240
@@ -409,16 +415,6 @@ void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
409415 auto &O = *OutStreamer;
410416 MCSymbol *CurSled = OutContext.createTempSymbol (" xray_sled_" , true );
411417 O.emitLabel (CurSled);
412- MCInst MovX0Op0 = MCInstBuilder (AArch64::ORRXrs)
413- .addReg (AArch64::X0)
414- .addReg (AArch64::XZR)
415- .addReg (MI.getOperand (0 ).getReg ())
416- .addImm (0 );
417- MCInst MovX1Op1 = MCInstBuilder (AArch64::ORRXrs)
418- .addReg (AArch64::X1)
419- .addReg (AArch64::XZR)
420- .addReg (MI.getOperand (1 ).getReg ())
421- .addImm (0 );
422418 bool MachO = TM.getTargetTriple ().isOSBinFormatMachO ();
423419 auto *Sym = MCSymbolRefExpr::create (
424420 OutContext.getOrCreateSymbol (
@@ -438,13 +434,9 @@ void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
438434 .addReg (AArch64::X2)
439435 .addReg (AArch64::SP)
440436 .addImm (2 ));
441- EmitToStreamer (O, MovX0Op0);
442- EmitToStreamer (O, MovX1Op1);
443- EmitToStreamer (O, MCInstBuilder (AArch64::ORRXrs)
444- .addReg (AArch64::X2)
445- .addReg (AArch64::XZR)
446- .addReg (MI.getOperand (2 ).getReg ())
447- .addImm (0 ));
437+ emitMovXReg (AArch64::X0, MI.getOperand (0 ).getReg ());
438+ emitMovXReg (AArch64::X1, MI.getOperand (1 ).getReg ());
439+ emitMovXReg (AArch64::X2, MI.getOperand (2 ).getReg ());
448440 EmitToStreamer (O, MCInstBuilder (AArch64::BL).addExpr (Sym));
449441 EmitToStreamer (O, MCInstBuilder (AArch64::LDRXui)
450442 .addReg (AArch64::X2)
@@ -468,8 +460,8 @@ void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
468460 .addReg (AArch64::X1)
469461 .addReg (AArch64::SP)
470462 .addImm (-2 ));
471- EmitToStreamer (O, MovX0Op0 );
472- EmitToStreamer (O, MovX1Op1 );
463+ emitMovXReg (AArch64::X0, MI. getOperand ( 0 ). getReg () );
464+ emitMovXReg (AArch64::X1, MI. getOperand ( 1 ). getReg () );
473465 EmitToStreamer (O, MCInstBuilder (AArch64::BL).addExpr (Sym));
474466 O.AddComment (" End XRay custom event" );
475467 EmitToStreamer (O, MCInstBuilder (AArch64::LDPXpost)
@@ -497,11 +489,7 @@ void AArch64AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
497489 // Checking XZR makes no sense. Instead of emitting a load, zero
498490 // ScratchRegs[0] and use it for the ESR AddrIndex below.
499491 AddrReg = getXRegFromWReg (ScratchRegs[0 ]);
500- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::ORRXrs)
501- .addReg (AddrReg)
502- .addReg (AArch64::XZR)
503- .addReg (AArch64::XZR)
504- .addImm (0 ));
492+ emitMovXReg (AddrReg, AArch64::XZR);
505493 } else {
506494 // If one of the scratch registers is used for the call target (e.g.
507495 // with AArch64::TCRETURNriBTI), we can clobber another caller-saved
@@ -534,16 +522,8 @@ void AArch64AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
534522
535523 // Load the expected type hash.
536524 const int64_t Type = MI.getOperand (1 ).getImm ();
537- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::MOVKWi)
538- .addReg (ScratchRegs[1 ])
539- .addReg (ScratchRegs[1 ])
540- .addImm (Type & 0xFFFF )
541- .addImm (0 ));
542- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::MOVKWi)
543- .addReg (ScratchRegs[1 ])
544- .addReg (ScratchRegs[1 ])
545- .addImm ((Type >> 16 ) & 0xFFFF )
546- .addImm (16 ));
525+ emitMOVK (ScratchRegs[1 ], Type & 0xFFFF , 0 );
526+ emitMOVK (ScratchRegs[1 ], (Type >> 16 ) & 0xFFFF , 16 );
547527
548528 // Compare the hashes and trap if there's a mismatch.
549529 EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::SUBSWrs)
@@ -627,6 +607,7 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
627607 std::unique_ptr<MCSubtargetInfo> STI (
628608 TM.getTarget ().createMCSubtargetInfo (TT.str (), " " , " " ));
629609 assert (STI && " Unable to create subtarget info" );
610+ this ->STI = static_cast <const AArch64Subtarget *>(&*STI);
630611
631612 MCSymbol *HwasanTagMismatchV1Sym =
632613 OutContext.getOrCreateSymbol (" __hwasan_tag_mismatch" );
@@ -679,11 +660,7 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
679660 // Fortuitously, kShadowBaseAlignment == 32, so we use the 32-bit
680661 // left-shift option in the MOV instruction. Combined with the 16-bit
681662 // immediate, this is enough to represent any offset up to 2**48.
682- OutStreamer->emitInstruction (MCInstBuilder (AArch64::MOVZXi)
683- .addReg (AArch64::X17)
684- .addImm (FixedShadowOffset >> 32 )
685- .addImm (32 ),
686- *STI);
663+ emitMOVZ (AArch64::X17, FixedShadowOffset >> 32 , 32 );
687664 OutStreamer->emitInstruction (MCInstBuilder (AArch64::LDRBBroX)
688665 .addReg (AArch64::W16)
689666 .addReg (AArch64::X17)
@@ -823,18 +800,8 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
823800 *STI);
824801
825802 if (Reg != AArch64::X0)
826- OutStreamer->emitInstruction (MCInstBuilder (AArch64::ORRXrs)
827- .addReg (AArch64::X0)
828- .addReg (AArch64::XZR)
829- .addReg (Reg)
830- .addImm (0 ),
831- *STI);
832- OutStreamer->emitInstruction (
833- MCInstBuilder (AArch64::MOVZXi)
834- .addReg (AArch64::X1)
835- .addImm (AccessInfo & HWASanAccessInfo::RuntimeMask)
836- .addImm (0 ),
837- *STI);
803+ emitMovXReg (AArch64::X0, Reg);
804+ emitMOVZ (AArch64::X1, AccessInfo & HWASanAccessInfo::RuntimeMask, 0 );
838805
839806 if (CompileKernel) {
840807 // The Linux kernel's dynamic loader doesn't support GOT relative
@@ -865,6 +832,7 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
865832 MCInstBuilder (AArch64::BR).addReg (AArch64::X16), *STI);
866833 }
867834 }
835+ this ->STI = nullptr ;
868836}
869837
870838static void emitAuthenticatedPointer (MCStreamer &OutStreamer,
@@ -1438,24 +1406,16 @@ void AArch64AsmPrinter::LowerHardenedBRJumpTable(const MachineInstr &MI) {
14381406 .addImm (0 ));
14391407 ++InstsEmitted;
14401408 } else {
1441- EmitToStreamer (*OutStreamer,
1442- MCInstBuilder (AArch64::MOVZXi)
1443- .addReg (AArch64::X17)
1444- .addImm (static_cast <uint16_t >(MaxTableEntry))
1445- .addImm (0 ));
1409+ emitMOVZ (AArch64::X17, static_cast <uint16_t >(MaxTableEntry), 0 );
14461410 ++InstsEmitted;
14471411 // It's sad that we have to manually materialize instructions, but we can't
14481412 // trivially reuse the main pseudo expansion logic.
14491413 // A MOVK sequence is easy enough to generate and handles the general case.
14501414 for (int Offset = 16 ; Offset < 64 ; Offset += 16 ) {
14511415 if ((MaxTableEntry >> Offset) == 0 )
14521416 break ;
1453- EmitToStreamer (*OutStreamer,
1454- MCInstBuilder (AArch64::MOVKXi)
1455- .addReg (AArch64::X17)
1456- .addReg (AArch64::X17)
1457- .addImm (static_cast <uint16_t >(MaxTableEntry >> Offset))
1458- .addImm (Offset));
1417+ emitMOVK (AArch64::X17, static_cast <uint16_t >(MaxTableEntry >> Offset),
1418+ Offset);
14591419 ++InstsEmitted;
14601420 }
14611421 EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::SUBSXrs)
@@ -1615,20 +1575,9 @@ void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
16151575 Register ScratchReg = MI.getOperand (Opers.getNextScratchIdx ()).getReg ();
16161576 EncodedBytes = 16 ;
16171577 // Materialize the jump address:
1618- EmitToStreamer (OutStreamer, MCInstBuilder (AArch64::MOVZXi)
1619- .addReg (ScratchReg)
1620- .addImm ((CallTarget >> 32 ) & 0xFFFF )
1621- .addImm (32 ));
1622- EmitToStreamer (OutStreamer, MCInstBuilder (AArch64::MOVKXi)
1623- .addReg (ScratchReg)
1624- .addReg (ScratchReg)
1625- .addImm ((CallTarget >> 16 ) & 0xFFFF )
1626- .addImm (16 ));
1627- EmitToStreamer (OutStreamer, MCInstBuilder (AArch64::MOVKXi)
1628- .addReg (ScratchReg)
1629- .addReg (ScratchReg)
1630- .addImm (CallTarget & 0xFFFF )
1631- .addImm (0 ));
1578+ emitMOVZ (ScratchReg, (CallTarget >> 32 ) & 0xFFFF , 32 );
1579+ emitMOVK (ScratchReg, (CallTarget >> 16 ) & 0xFFFF , 16 );
1580+ emitMOVK (ScratchReg, CallTarget & 0xFFFF , 0 );
16321581 EmitToStreamer (OutStreamer, MCInstBuilder (AArch64::BLR).addReg (ScratchReg));
16331582 }
16341583 // Emit padding.
@@ -1717,6 +1666,33 @@ void AArch64AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI) {
17171666 OutStreamer->emitInstruction (MI, getSubtargetInfo ());
17181667}
17191668
1669+ void AArch64AsmPrinter::emitMovXReg (Register Dest, Register Src) {
1670+ EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::ORRXrs)
1671+ .addReg (Dest)
1672+ .addReg (AArch64::XZR)
1673+ .addReg (Src)
1674+ .addImm (0 ));
1675+ }
1676+
1677+ void AArch64AsmPrinter::emitMOVZ (Register Dest, uint64_t Imm, unsigned Shift) {
1678+ bool Is64Bit = AArch64::GPR64RegClass.contains (Dest);
1679+ EmitToStreamer (*OutStreamer,
1680+ MCInstBuilder (Is64Bit ? AArch64::MOVZXi : AArch64::MOVZWi)
1681+ .addReg (Dest)
1682+ .addImm (Imm)
1683+ .addImm (Shift));
1684+ }
1685+
1686+ void AArch64AsmPrinter::emitMOVK (Register Dest, uint64_t Imm, unsigned Shift) {
1687+ bool Is64Bit = AArch64::GPR64RegClass.contains (Dest);
1688+ EmitToStreamer (*OutStreamer,
1689+ MCInstBuilder (Is64Bit ? AArch64::MOVKXi : AArch64::MOVKWi)
1690+ .addReg (Dest)
1691+ .addReg (Dest)
1692+ .addImm (Imm)
1693+ .addImm (Shift));
1694+ }
1695+
17201696void AArch64AsmPrinter::emitFMov0 (const MachineInstr &MI) {
17211697 Register DestReg = MI.getOperand (0 ).getReg ();
17221698 if (STI->hasZeroCycleZeroingFP () && !STI->hasZeroCycleZeroingFPWorkaround () &&
@@ -1774,26 +1750,15 @@ unsigned AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
17741750
17751751 // If there's only a constant discriminator, MOV it into x17.
17761752 if (AddrDisc == AArch64::XZR) {
1777- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::MOVZXi)
1778- .addReg (AArch64::X17)
1779- .addImm (Disc)
1780- .addImm (/* shift=*/ 0 ));
1753+ emitMOVZ (AArch64::X17, Disc, 0 );
17811754 ++InstsEmitted;
17821755 return AArch64::X17;
17831756 }
17841757
17851758 // If there are both, emit a blend into x17.
1786- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::ORRXrs)
1787- .addReg (AArch64::X17)
1788- .addReg (AArch64::XZR)
1789- .addReg (AddrDisc)
1790- .addImm (0 ));
1759+ emitMovXReg (AArch64::X17, AddrDisc);
17911760 ++InstsEmitted;
1792- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::MOVKXi)
1793- .addReg (AArch64::X17)
1794- .addReg (AArch64::X17)
1795- .addImm (Disc)
1796- .addImm (/* shift=*/ 48 ));
1761+ emitMOVK (AArch64::X17, Disc, 48 );
17971762 ++InstsEmitted;
17981763 return AArch64::X17;
17991764}
@@ -1914,11 +1879,7 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
19141879
19151880 // XPAC has tied src/dst: use x17 as a temporary copy.
19161881 // mov x17, x16
1917- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::ORRXrs)
1918- .addReg (AArch64::X17)
1919- .addReg (AArch64::XZR)
1920- .addReg (AArch64::X16)
1921- .addImm (0 ));
1882+ emitMovXReg (AArch64::X17, AArch64::X16);
19221883 ++InstsEmitted;
19231884
19241885 // xpaci x17
@@ -1955,11 +1916,7 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
19551916 // FIXME: can we simply return the AUT result, already in x16? without..
19561917 // ..traps this is usable as an oracle anyway, based on high bits
19571918 // mov x17, x16
1958- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::ORRXrs)
1959- .addReg (AArch64::X16)
1960- .addReg (AArch64::XZR)
1961- .addReg (AArch64::X17)
1962- .addImm (0 ));
1919+ emitMovXReg (AArch64::X16, AArch64::X17);
19631920 ++InstsEmitted;
19641921
19651922 if (IsAUTPAC) {
@@ -2273,13 +2230,9 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
22732230 return true ;
22742231 return false ;
22752232 };
2276- for (int BitPos = 16 ; BitPos != 64 && NeedMovk (BitPos); BitPos += 16 ) {
2277- EmitAndIncrement (MCInstBuilder (AArch64::MOVKXi)
2278- .addReg (AArch64::X17)
2279- .addReg (AArch64::X17)
2280- .addImm ((UOffset >> BitPos) & 0xffff )
2281- .addImm (/* shift=*/ BitPos));
2282- }
2233+ for (int BitPos = 16 ; BitPos != 64 && NeedMovk (BitPos); BitPos += 16 )
2234+ emitMOVK (AArch64::X17, (UOffset >> BitPos) & 0xffff , BitPos);
2235+
22832236 EmitAndIncrement (MCInstBuilder (AArch64::ADDXrs)
22842237 .addReg (AArch64::X16)
22852238 .addReg (AArch64::X16)
@@ -2291,21 +2244,10 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
22912244 unsigned DiscReg = AddrDisc;
22922245 if (Disc != 0 ) {
22932246 if (AddrDisc != AArch64::XZR) {
2294- EmitAndIncrement (MCInstBuilder (AArch64::ORRXrs)
2295- .addReg (AArch64::X17)
2296- .addReg (AArch64::XZR)
2297- .addReg (AddrDisc)
2298- .addImm (0 ));
2299- EmitAndIncrement (MCInstBuilder (AArch64::MOVKXi)
2300- .addReg (AArch64::X17)
2301- .addReg (AArch64::X17)
2302- .addImm (Disc)
2303- .addImm (/* shift=*/ 48 ));
2247+ emitMovXReg (AArch64::X17, AddrDisc);
2248+ emitMOVK (AArch64::X17, Disc, 48 );
23042249 } else {
2305- EmitAndIncrement (MCInstBuilder (AArch64::MOVZXi)
2306- .addReg (AArch64::X17)
2307- .addImm (Disc)
2308- .addImm (/* shift=*/ 0 ));
2250+ emitMOVZ (AArch64::X17, Disc, 0 );
23092251 }
23102252 DiscReg = AArch64::X17;
23112253 }
@@ -2337,6 +2279,10 @@ AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
23372279// instructions) auto-generated.
23382280#include " AArch64GenMCPseudoLowering.inc"
23392281
2282+ void AArch64AsmPrinter::EmitToStreamer (MCStreamer &S, const MCInst &Inst) {
2283+ S.emitInstruction (Inst, *STI);
2284+ }
2285+
23402286void AArch64AsmPrinter::emitInstruction (const MachineInstr *MI) {
23412287 AArch64_MC::verifyInstructionPredicates (MI->getOpcode (), STI->getFeatureBits ());
23422288
@@ -2511,21 +2457,10 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
25112457 if (Disc) {
25122458 if (AddrDisc != AArch64::NoRegister) {
25132459 if (ScratchReg != AddrDisc)
2514- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::ORRXrs)
2515- .addReg (ScratchReg)
2516- .addReg (AArch64::XZR)
2517- .addReg (AddrDisc)
2518- .addImm (0 ));
2519- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::MOVKXi)
2520- .addReg (ScratchReg)
2521- .addReg (ScratchReg)
2522- .addImm (Disc)
2523- .addImm (/* shift=*/ 48 ));
2460+ emitMovXReg (ScratchReg, AddrDisc);
2461+ emitMOVK (ScratchReg, Disc, 48 );
25242462 } else {
2525- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::MOVZXi)
2526- .addReg (ScratchReg)
2527- .addImm (Disc)
2528- .addImm (/* shift=*/ 0 ));
2463+ emitMOVZ (ScratchReg, Disc, 0 );
25292464 }
25302465 DiscReg = ScratchReg;
25312466 }
0 commit comments