@@ -315,6 +315,7 @@ class AArch64AsmPrinter : public AsmPrinter {
315315
316316 // / Emit instruction to set float register to zero.
317317 void emitFMov0 (const MachineInstr &MI);
318+ void emitFMov0AsFMov (const MachineInstr &MI, Register DestReg);
318319
319320 using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
320321
@@ -1893,45 +1894,77 @@ void AArch64AsmPrinter::emitMOVK(Register Dest, uint64_t Imm, unsigned Shift) {
18931894
18941895void AArch64AsmPrinter::emitFMov0 (const MachineInstr &MI) {
18951896 Register DestReg = MI.getOperand (0 ).getReg ();
1896- if (STI->hasZeroCycleZeroingFP () && !STI->hasZeroCycleZeroingFPWorkaround () &&
1897- STI->isNeonAvailable ()) {
1898- // Convert H/S register to corresponding D register
1899- if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31)
1900- DestReg = AArch64::D0 + (DestReg - AArch64::H0);
1901- else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31)
1902- DestReg = AArch64::D0 + (DestReg - AArch64::S0);
1903- else
1904- assert (AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
1897+ if (!STI->hasZeroCycleZeroingFPWorkaround () && STI->isNeonAvailable ()) {
1898+ if (STI->hasZeroCycleZeroingFPR64 ()) {
1899+ // Convert H/S register to corresponding D register
1900+ const AArch64RegisterInfo *TRI = STI->getRegisterInfo ();
1901+ if (AArch64::FPR16RegClass.contains (DestReg))
1902+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::hsub,
1903+ &AArch64::FPR64RegClass);
1904+ else if (AArch64::FPR32RegClass.contains (DestReg))
1905+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::ssub,
1906+ &AArch64::FPR64RegClass);
1907+ else
1908+ assert (AArch64::FPR64RegClass.contains (DestReg));
1909+
1910+ MCInst MOVI;
1911+ MOVI.setOpcode (AArch64::MOVID);
1912+ MOVI.addOperand (MCOperand::createReg (DestReg));
1913+ MOVI.addOperand (MCOperand::createImm (0 ));
1914+ EmitToStreamer (*OutStreamer, MOVI);
1915+ } else if (STI->hasZeroCycleZeroingFPR128 ()) {
1916+ // Convert H/S/D register to corresponding Q register
1917+ const AArch64RegisterInfo *TRI = STI->getRegisterInfo ();
1918+ if (AArch64::FPR16RegClass.contains (DestReg)) {
1919+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::hsub,
1920+ &AArch64::FPR128RegClass);
1921+ } else if (AArch64::FPR32RegClass.contains (DestReg)) {
1922+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::ssub,
1923+ &AArch64::FPR128RegClass);
1924+ } else {
1925+ assert (AArch64::FPR64RegClass.contains (DestReg));
1926+ DestReg = TRI->getMatchingSuperReg (DestReg, AArch64::dsub,
1927+ &AArch64::FPR128RegClass);
1928+ }
19051929
1906- MCInst MOVI;
1907- MOVI.setOpcode (AArch64::MOVID);
1908- MOVI.addOperand (MCOperand::createReg (DestReg));
1909- MOVI.addOperand (MCOperand::createImm (0 ));
1910- EmitToStreamer (*OutStreamer, MOVI);
1911- } else {
1912- MCInst FMov;
1913- switch (MI.getOpcode ()) {
1914- default : llvm_unreachable (" Unexpected opcode" );
1915- case AArch64::FMOVH0:
1916- FMov.setOpcode (STI->hasFullFP16 () ? AArch64::FMOVWHr : AArch64::FMOVWSr);
1917- if (!STI->hasFullFP16 ())
1918- DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
1919- FMov.addOperand (MCOperand::createReg (DestReg));
1920- FMov.addOperand (MCOperand::createReg (AArch64::WZR));
1921- break ;
1922- case AArch64::FMOVS0:
1923- FMov.setOpcode (AArch64::FMOVWSr);
1924- FMov.addOperand (MCOperand::createReg (DestReg));
1925- FMov.addOperand (MCOperand::createReg (AArch64::WZR));
1926- break ;
1927- case AArch64::FMOVD0:
1928- FMov.setOpcode (AArch64::FMOVXDr);
1929- FMov.addOperand (MCOperand::createReg (DestReg));
1930- FMov.addOperand (MCOperand::createReg (AArch64::XZR));
1931- break ;
1930+ MCInst MOVI;
1931+ MOVI.setOpcode (AArch64::MOVIv2d_ns);
1932+ MOVI.addOperand (MCOperand::createReg (DestReg));
1933+ MOVI.addOperand (MCOperand::createImm (0 ));
1934+ EmitToStreamer (*OutStreamer, MOVI);
1935+ } else {
1936+ emitFMov0AsFMov (MI, DestReg);
19321937 }
1933- EmitToStreamer (*OutStreamer, FMov);
1938+ } else {
1939+ emitFMov0AsFMov (MI, DestReg);
1940+ }
1941+ }
1942+
1943+ void AArch64AsmPrinter::emitFMov0AsFMov (const MachineInstr &MI,
1944+ Register DestReg) {
1945+ MCInst FMov;
1946+ switch (MI.getOpcode ()) {
1947+ default :
1948+ llvm_unreachable (" Unexpected opcode" );
1949+ case AArch64::FMOVH0:
1950+ FMov.setOpcode (STI->hasFullFP16 () ? AArch64::FMOVWHr : AArch64::FMOVWSr);
1951+ if (!STI->hasFullFP16 ())
1952+ DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
1953+ FMov.addOperand (MCOperand::createReg (DestReg));
1954+ FMov.addOperand (MCOperand::createReg (AArch64::WZR));
1955+ break ;
1956+ case AArch64::FMOVS0:
1957+ FMov.setOpcode (AArch64::FMOVWSr);
1958+ FMov.addOperand (MCOperand::createReg (DestReg));
1959+ FMov.addOperand (MCOperand::createReg (AArch64::WZR));
1960+ break ;
1961+ case AArch64::FMOVD0:
1962+ FMov.setOpcode (AArch64::FMOVXDr);
1963+ FMov.addOperand (MCOperand::createReg (DestReg));
1964+ FMov.addOperand (MCOperand::createReg (AArch64::XZR));
1965+ break ;
19341966 }
1967+ EmitToStreamer (*OutStreamer, FMov);
19351968}
19361969
19371970Register AArch64AsmPrinter::emitPtrauthDiscriminator (uint16_t Disc,
@@ -2952,7 +2985,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
29522985 MCInst TmpInst;
29532986 TmpInst.setOpcode (AArch64::MOVIv16b_ns);
29542987 TmpInst.addOperand (MCOperand::createReg (MI->getOperand (0 ).getReg ()));
2955- TmpInst.addOperand (MCOperand::createImm (MI-> getOperand ( 1 ). getImm () ));
2988+ TmpInst.addOperand (MCOperand::createImm (0 ));
29562989 EmitToStreamer (*OutStreamer, TmpInst);
29572990 return ;
29582991 }
0 commit comments