================ @@ -3062,7 +3131,68 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters( Size = 2; Alignment = Align(2); break; + case RegPairInfo::VG: + StrOpc = AArch64::STRXui; + Size = 8; + Alignment = Align(8); + break; + } + + unsigned X0Scratch = AArch64::NoRegister; + if (Reg1 == AArch64::VG) { + // Find an available register to store value of VG to. + Reg1 = findScratchNonCalleeSaveRegister(&MBB); + assert(Reg1 != AArch64::NoRegister); + SMEAttrs Attrs(MF.getFunction()); + + if (Attrs.hasStreamingBody() && !Attrs.hasStreamingInterface() && + AFI->getStreamingVGIdx() == std::numeric_limits<int>::max()) { + // For locally-streaming functions, we need to store both the streaming + // & non-streaming VG. Spill the streaming value first. + BuildMI(MBB, MI, DL, TII.get(AArch64::RDSVLI_XI), Reg1) + .addImm(1) + .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MI, DL, TII.get(AArch64::UBFMXri), Reg1) + .addReg(Reg1) + .addImm(3) + .addImm(63) + .setMIFlag(MachineInstr::FrameSetup); + + AFI->setStreamingVGIdx(RPI.FrameIdx); + } else { + if (HasSVE) + BuildMI(MBB, MI, DL, TII.get(AArch64::CNTD_XPiI), Reg1) + .addImm(31) + .addImm(1) + .setMIFlag(MachineInstr::FrameSetup); + else { + const AArch64Subtarget &STI = MF.getSubtarget<AArch64Subtarget>(); + for (const auto &LiveIn : MBB.liveins()) + if (STI.getRegisterInfo()->isSuperOrSubRegisterEq(AArch64::X0, + LiveIn.PhysReg)) + X0Scratch = Reg1; ---------------- sdesmalen-arm wrote:
Is this missing a `break` ? If so, you can write this using any_of, e.g.: ``` if (llvm::any_of(MBB.liveins(), [&STI](const RegisterMaskPair &LiveIn) { return STI.getRegisterInfo()->isSuperOrSubRegisterEq(AArch64::X0, LiveIn.PhysReg); })) X0Scratch = Reg1; ``` https://github.com/llvm/llvm-project/pull/83301 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits