@@ -307,6 +307,7 @@ class AArch64AsmPrinter : public AsmPrinter {
307
307
308
308
// / Emit instruction to set float register to zero.
309
309
void emitFMov0 (const MachineInstr &MI);
310
+ void emitFMov0AsFMov (const MachineInstr &MI, Register DestReg);
310
311
311
312
using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
312
313
@@ -1829,45 +1830,77 @@ void AArch64AsmPrinter::emitMOVK(Register Dest, uint64_t Imm, unsigned Shift) {
1829
1830
1830
1831
void AArch64AsmPrinter::emitFMov0 (const MachineInstr &MI) {
1831
1832
Register DestReg = MI.getOperand (0 ).getReg ();
1832
- if (STI->hasZeroCycleZeroingFPR64 () &&
1833
- !STI->hasZeroCycleZeroingFPWorkaround () && STI->isNeonAvailable ()) {
1834
- // Convert H/S register to corresponding D register
1835
- if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31)
1836
- DestReg = AArch64::D0 + (DestReg - AArch64::H0);
1837
- else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31)
1838
- DestReg = AArch64::D0 + (DestReg - AArch64::S0);
1839
- else
1840
- assert (AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
1833
+ if (!STI->hasZeroCycleZeroingFPWorkaround () && STI->isNeonAvailable ()) {
1834
+ if (STI->hasZeroCycleZeroingFPR64 ()) {
1835
+ // Convert H/S register to corresponding D register
1836
+ const AArch64RegisterInfo *TRI = STI->getRegisterInfo ();
1837
+ if (AArch64::FPR16RegClass.contains (DestReg))
1838
+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::hsub,
1839
+ &AArch64::FPR64RegClass);
1840
+ else if (AArch64::FPR32RegClass.contains (DestReg))
1841
+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::ssub,
1842
+ &AArch64::FPR64RegClass);
1843
+ else
1844
+ assert (AArch64::FPR64RegClass.contains (DestReg));
1845
+
1846
+ MCInst MOVI;
1847
+ MOVI.setOpcode (AArch64::MOVID);
1848
+ MOVI.addOperand (MCOperand::createReg (DestReg));
1849
+ MOVI.addOperand (MCOperand::createImm (0 ));
1850
+ EmitToStreamer (*OutStreamer, MOVI);
1851
+ } else if (STI->hasZeroCycleZeroingFPR128 ()) {
1852
+ // Convert H/S/D register to corresponding Q register
1853
+ const AArch64RegisterInfo *TRI = STI->getRegisterInfo ();
1854
+ if (AArch64::FPR16RegClass.contains (DestReg)) {
1855
+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::hsub,
1856
+ &AArch64::FPR128RegClass);
1857
+ } else if (AArch64::FPR32RegClass.contains (DestReg)) {
1858
+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::ssub,
1859
+ &AArch64::FPR128RegClass);
1860
+ } else {
1861
+ assert (AArch64::FPR64RegClass.contains (DestReg));
1862
+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::dsub,
1863
+ &AArch64::FPR128RegClass);
1864
+ }
1841
1865
1842
- MCInst MOVI;
1843
- MOVI.setOpcode (AArch64::MOVID);
1844
- MOVI.addOperand (MCOperand::createReg (DestReg));
1845
- MOVI.addOperand (MCOperand::createImm (0 ));
1846
- EmitToStreamer (*OutStreamer, MOVI);
1847
- } else {
1848
- MCInst FMov;
1849
- switch (MI.getOpcode ()) {
1850
- default : llvm_unreachable (" Unexpected opcode" );
1851
- case AArch64::FMOVH0:
1852
- FMov.setOpcode (STI->hasFullFP16 () ? AArch64::FMOVWHr : AArch64::FMOVWSr);
1853
- if (!STI->hasFullFP16 ())
1854
- DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
1855
- FMov.addOperand (MCOperand::createReg (DestReg));
1856
- FMov.addOperand (MCOperand::createReg (AArch64::WZR));
1857
- break ;
1858
- case AArch64::FMOVS0:
1859
- FMov.setOpcode (AArch64::FMOVWSr);
1860
- FMov.addOperand (MCOperand::createReg (DestReg));
1861
- FMov.addOperand (MCOperand::createReg (AArch64::WZR));
1862
- break ;
1863
- case AArch64::FMOVD0:
1864
- FMov.setOpcode (AArch64::FMOVXDr);
1865
- FMov.addOperand (MCOperand::createReg (DestReg));
1866
- FMov.addOperand (MCOperand::createReg (AArch64::XZR));
1867
- break ;
1866
+ MCInst MOVI;
1867
+ MOVI.setOpcode (AArch64::MOVIv2d_ns);
1868
+ MOVI.addOperand (MCOperand::createReg (DestReg));
1869
+ MOVI.addOperand (MCOperand::createImm (0 ));
1870
+ EmitToStreamer (*OutStreamer, MOVI);
1871
+ } else {
1872
+ emitFMov0AsFMov (MI, DestReg);
1868
1873
}
1869
- EmitToStreamer (*OutStreamer, FMov);
1874
+ } else {
1875
+ emitFMov0AsFMov (MI, DestReg);
1876
+ }
1877
+ }
1878
+
1879
+ void AArch64AsmPrinter::emitFMov0AsFMov (const MachineInstr &MI,
1880
+ Register DestReg) {
1881
+ MCInst FMov;
1882
+ switch (MI.getOpcode ()) {
1883
+ default :
1884
+ llvm_unreachable (" Unexpected opcode" );
1885
+ case AArch64::FMOVH0:
1886
+ FMov.setOpcode (STI->hasFullFP16 () ? AArch64::FMOVWHr : AArch64::FMOVWSr);
1887
+ if (!STI->hasFullFP16 ())
1888
+ DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
1889
+ FMov.addOperand (MCOperand::createReg (DestReg));
1890
+ FMov.addOperand (MCOperand::createReg (AArch64::WZR));
1891
+ break ;
1892
+ case AArch64::FMOVS0:
1893
+ FMov.setOpcode (AArch64::FMOVWSr);
1894
+ FMov.addOperand (MCOperand::createReg (DestReg));
1895
+ FMov.addOperand (MCOperand::createReg (AArch64::WZR));
1896
+ break ;
1897
+ case AArch64::FMOVD0:
1898
+ FMov.setOpcode (AArch64::FMOVXDr);
1899
+ FMov.addOperand (MCOperand::createReg (DestReg));
1900
+ FMov.addOperand (MCOperand::createReg (AArch64::XZR));
1901
+ break ;
1870
1902
}
1903
+ EmitToStreamer (*OutStreamer, FMov);
1871
1904
}
1872
1905
1873
1906
Register AArch64AsmPrinter::emitPtrauthDiscriminator (uint16_t Disc,
0 commit comments