@@ -164,6 +164,8 @@ class AArch64AsmPrinter : public AsmPrinter {
164
164
// / pseudo instructions.
165
165
bool lowerPseudoInstExpansion (const MachineInstr *MI, MCInst &Inst);
166
166
167
+ void EmitToStreamer (MCStreamer &S, const MCInst &Inst);
168
+
167
169
void emitInstruction (const MachineInstr *MI) override ;
168
170
169
171
void emitFunctionHeaderComment () override ;
@@ -229,6 +231,10 @@ class AArch64AsmPrinter : public AsmPrinter {
229
231
// / Emit the LOHs contained in AArch64FI.
230
232
void emitLOHs ();
231
233
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
+
232
238
// / Emit instruction to set float register to zero.
233
239
void emitFMov0 (const MachineInstr &MI);
234
240
@@ -409,16 +415,6 @@ void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
409
415
auto &O = *OutStreamer;
410
416
MCSymbol *CurSled = OutContext.createTempSymbol (" xray_sled_" , true );
411
417
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 );
422
418
bool MachO = TM.getTargetTriple ().isOSBinFormatMachO ();
423
419
auto *Sym = MCSymbolRefExpr::create (
424
420
OutContext.getOrCreateSymbol (
@@ -438,13 +434,9 @@ void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
438
434
.addReg (AArch64::X2)
439
435
.addReg (AArch64::SP)
440
436
.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 ());
448
440
EmitToStreamer (O, MCInstBuilder (AArch64::BL).addExpr (Sym));
449
441
EmitToStreamer (O, MCInstBuilder (AArch64::LDRXui)
450
442
.addReg (AArch64::X2)
@@ -468,8 +460,8 @@ void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
468
460
.addReg (AArch64::X1)
469
461
.addReg (AArch64::SP)
470
462
.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 () );
473
465
EmitToStreamer (O, MCInstBuilder (AArch64::BL).addExpr (Sym));
474
466
O.AddComment (" End XRay custom event" );
475
467
EmitToStreamer (O, MCInstBuilder (AArch64::LDPXpost)
@@ -497,11 +489,7 @@ void AArch64AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
497
489
// Checking XZR makes no sense. Instead of emitting a load, zero
498
490
// ScratchRegs[0] and use it for the ESR AddrIndex below.
499
491
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);
505
493
} else {
506
494
// If one of the scratch registers is used for the call target (e.g.
507
495
// with AArch64::TCRETURNriBTI), we can clobber another caller-saved
@@ -534,16 +522,8 @@ void AArch64AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
534
522
535
523
// Load the expected type hash.
536
524
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 );
547
527
548
528
// Compare the hashes and trap if there's a mismatch.
549
529
EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::SUBSWrs)
@@ -627,6 +607,7 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
627
607
std::unique_ptr<MCSubtargetInfo> STI (
628
608
TM.getTarget ().createMCSubtargetInfo (TT.str (), " " , " " ));
629
609
assert (STI && " Unable to create subtarget info" );
610
+ this ->STI = static_cast <const AArch64Subtarget *>(&*STI);
630
611
631
612
MCSymbol *HwasanTagMismatchV1Sym =
632
613
OutContext.getOrCreateSymbol (" __hwasan_tag_mismatch" );
@@ -679,11 +660,7 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
679
660
// Fortuitously, kShadowBaseAlignment == 32, so we use the 32-bit
680
661
// left-shift option in the MOV instruction. Combined with the 16-bit
681
662
// 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 );
687
664
OutStreamer->emitInstruction (MCInstBuilder (AArch64::LDRBBroX)
688
665
.addReg (AArch64::W16)
689
666
.addReg (AArch64::X17)
@@ -823,18 +800,8 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
823
800
*STI);
824
801
825
802
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 );
838
805
839
806
if (CompileKernel) {
840
807
// The Linux kernel's dynamic loader doesn't support GOT relative
@@ -865,6 +832,7 @@ void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
865
832
MCInstBuilder (AArch64::BR).addReg (AArch64::X16), *STI);
866
833
}
867
834
}
835
+ this ->STI = nullptr ;
868
836
}
869
837
870
838
static void emitAuthenticatedPointer (MCStreamer &OutStreamer,
@@ -1438,24 +1406,16 @@ void AArch64AsmPrinter::LowerHardenedBRJumpTable(const MachineInstr &MI) {
1438
1406
.addImm (0 ));
1439
1407
++InstsEmitted;
1440
1408
} 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 );
1446
1410
++InstsEmitted;
1447
1411
// It's sad that we have to manually materialize instructions, but we can't
1448
1412
// trivially reuse the main pseudo expansion logic.
1449
1413
// A MOVK sequence is easy enough to generate and handles the general case.
1450
1414
for (int Offset = 16 ; Offset < 64 ; Offset += 16 ) {
1451
1415
if ((MaxTableEntry >> Offset) == 0 )
1452
1416
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);
1459
1419
++InstsEmitted;
1460
1420
}
1461
1421
EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::SUBSXrs)
@@ -1615,20 +1575,9 @@ void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
1615
1575
Register ScratchReg = MI.getOperand (Opers.getNextScratchIdx ()).getReg ();
1616
1576
EncodedBytes = 16 ;
1617
1577
// 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 );
1632
1581
EmitToStreamer (OutStreamer, MCInstBuilder (AArch64::BLR).addReg (ScratchReg));
1633
1582
}
1634
1583
// Emit padding.
@@ -1717,6 +1666,33 @@ void AArch64AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI) {
1717
1666
OutStreamer->emitInstruction (MI, getSubtargetInfo ());
1718
1667
}
1719
1668
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
+
1720
1696
void AArch64AsmPrinter::emitFMov0 (const MachineInstr &MI) {
1721
1697
Register DestReg = MI.getOperand (0 ).getReg ();
1722
1698
if (STI->hasZeroCycleZeroingFP () && !STI->hasZeroCycleZeroingFPWorkaround () &&
@@ -1774,26 +1750,15 @@ unsigned AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
1774
1750
1775
1751
// If there's only a constant discriminator, MOV it into x17.
1776
1752
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 );
1781
1754
++InstsEmitted;
1782
1755
return AArch64::X17;
1783
1756
}
1784
1757
1785
1758
// 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);
1791
1760
++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 );
1797
1762
++InstsEmitted;
1798
1763
return AArch64::X17;
1799
1764
}
@@ -1914,11 +1879,7 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
1914
1879
1915
1880
// XPAC has tied src/dst: use x17 as a temporary copy.
1916
1881
// 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);
1922
1883
++InstsEmitted;
1923
1884
1924
1885
// xpaci x17
@@ -1955,11 +1916,7 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
1955
1916
// FIXME: can we simply return the AUT result, already in x16? without..
1956
1917
// ..traps this is usable as an oracle anyway, based on high bits
1957
1918
// 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);
1963
1920
++InstsEmitted;
1964
1921
1965
1922
if (IsAUTPAC) {
@@ -2273,13 +2230,9 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
2273
2230
return true ;
2274
2231
return false ;
2275
2232
};
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
+
2283
2236
EmitAndIncrement (MCInstBuilder (AArch64::ADDXrs)
2284
2237
.addReg (AArch64::X16)
2285
2238
.addReg (AArch64::X16)
@@ -2291,21 +2244,10 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
2291
2244
unsigned DiscReg = AddrDisc;
2292
2245
if (Disc != 0 ) {
2293
2246
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 );
2304
2249
} else {
2305
- EmitAndIncrement (MCInstBuilder (AArch64::MOVZXi)
2306
- .addReg (AArch64::X17)
2307
- .addImm (Disc)
2308
- .addImm (/* shift=*/ 0 ));
2250
+ emitMOVZ (AArch64::X17, Disc, 0 );
2309
2251
}
2310
2252
DiscReg = AArch64::X17;
2311
2253
}
@@ -2337,6 +2279,10 @@ AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
2337
2279
// instructions) auto-generated.
2338
2280
#include " AArch64GenMCPseudoLowering.inc"
2339
2281
2282
+ void AArch64AsmPrinter::EmitToStreamer (MCStreamer &S, const MCInst &Inst) {
2283
+ S.emitInstruction (Inst, *STI);
2284
+ }
2285
+
2340
2286
void AArch64AsmPrinter::emitInstruction (const MachineInstr *MI) {
2341
2287
AArch64_MC::verifyInstructionPredicates (MI->getOpcode (), STI->getFeatureBits ());
2342
2288
@@ -2511,21 +2457,10 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
2511
2457
if (Disc) {
2512
2458
if (AddrDisc != AArch64::NoRegister) {
2513
2459
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 );
2524
2462
} else {
2525
- EmitToStreamer (*OutStreamer, MCInstBuilder (AArch64::MOVZXi)
2526
- .addReg (ScratchReg)
2527
- .addImm (Disc)
2528
- .addImm (/* shift=*/ 0 ));
2463
+ emitMOVZ (ScratchReg, Disc, 0 );
2529
2464
}
2530
2465
DiscReg = ScratchReg;
2531
2466
}
0 commit comments