@@ -307,6 +307,7 @@ class AArch64AsmPrinter : public AsmPrinter {
307307
308308 // / Emit instruction to set float register to zero.
309309 void emitFMov0 (const MachineInstr &MI);
310+ void emitFMov0AsFMov (const MachineInstr &MI, Register DestReg);
310311
311312 using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
312313
@@ -1829,45 +1830,77 @@ void AArch64AsmPrinter::emitMOVK(Register Dest, uint64_t Imm, unsigned Shift) {
18291830
18301831void AArch64AsmPrinter::emitFMov0 (const MachineInstr &MI) {
18311832 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+ }
18411865
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);
18681873 }
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 ;
18701902 }
1903+ EmitToStreamer (*OutStreamer, FMov);
18711904}
18721905
18731906Register AArch64AsmPrinter::emitPtrauthDiscriminator (uint16_t Disc,
0 commit comments