@@ -82,8 +82,8 @@ enum ZAState {
8282 // A ZA save has been set up or committed (i.e. ZA is dormant or off)
8383 LOCAL_SAVED,
8484
85- // ZA is off or a lazy save has been set up by the caller
86- CALLER_DORMANT ,
85+ // The ZA/ZT0 state on entry to the function.
86+ ENTRY ,
8787
8888 // ZA is off
8989 OFF,
@@ -200,7 +200,7 @@ StringRef getZAStateString(ZAState State) {
200200 MAKE_CASE (ZAState::ANY)
201201 MAKE_CASE (ZAState::ACTIVE)
202202 MAKE_CASE (ZAState::LOCAL_SAVED)
203- MAKE_CASE (ZAState::CALLER_DORMANT )
203+ MAKE_CASE (ZAState::ENTRY )
204204 MAKE_CASE (ZAState::OFF)
205205 default :
206206 llvm_unreachable (" Unexpected ZAState" );
@@ -281,8 +281,8 @@ struct MachineSMEABI : public MachineFunctionPass {
281281 void propagateDesiredStates (FunctionInfo &FnInfo, bool Forwards = true );
282282
283283 // Emission routines for private and shared ZA functions (using lazy saves).
284- void emitNewZAPrologue (MachineBasicBlock &MBB,
285- MachineBasicBlock::iterator MBBI);
284+ void emitSMEPrologue (MachineBasicBlock &MBB,
285+ MachineBasicBlock::iterator MBBI);
286286 void emitRestoreLazySave (EmitContext &, MachineBasicBlock &MBB,
287287 MachineBasicBlock::iterator MBBI,
288288 LiveRegs PhysLiveRegs);
@@ -406,9 +406,7 @@ FunctionInfo MachineSMEABI::collectNeededZAStates(SMEAttrs SMEFnAttrs) {
406406
407407 if (MBB.isEntryBlock ()) {
408408 // Entry block:
409- Block.FixedEntryState = SMEFnAttrs.hasPrivateZAInterface ()
410- ? ZAState::CALLER_DORMANT
411- : ZAState::ACTIVE;
409+ Block.FixedEntryState = ZAState::ENTRY;
412410 } else if (MBB.isEHPad ()) {
413411 // EH entry block:
414412 Block.FixedEntryState = ZAState::LOCAL_SAVED;
@@ -825,32 +823,49 @@ void MachineSMEABI::emitAllocateLazySaveBuffer(
825823 }
826824}
827825
828- void MachineSMEABI::emitNewZAPrologue (MachineBasicBlock &MBB,
829- MachineBasicBlock::iterator MBBI) {
826+ static constexpr unsigned ZERO_ALL_ZA_MASK = 0b11111111 ;
827+
828+ void MachineSMEABI::emitSMEPrologue (MachineBasicBlock &MBB,
829+ MachineBasicBlock::iterator MBBI) {
830830 auto *TLI = Subtarget->getTargetLowering ();
831831 DebugLoc DL = getDebugLoc (MBB, MBBI);
832832
833- // Get current TPIDR2_EL0.
834- Register TPIDR2EL0 = MRI->createVirtualRegister (&AArch64::GPR64RegClass);
835- BuildMI (MBB, MBBI, DL, TII->get (AArch64::MRS))
836- .addReg (TPIDR2EL0, RegState::Define)
837- .addImm (AArch64SysReg::TPIDR2_EL0);
838- // If TPIDR2_EL0 is non-zero, commit the lazy save.
839- // NOTE: Functions that only use ZT0 don't need to zero ZA.
840- bool ZeroZA = AFI->getSMEFnAttrs ().hasZAState ();
841- auto CommitZASave =
842- BuildMI (MBB, MBBI, DL, TII->get (AArch64::CommitZASavePseudo))
843- .addReg (TPIDR2EL0)
844- .addImm (ZeroZA ? 1 : 0 )
845- .addImm (/* ZeroZT0=*/ false )
846- .addExternalSymbol (TLI->getLibcallName (RTLIB::SMEABI_TPIDR2_SAVE))
847- .addRegMask (TRI->SMEABISupportRoutinesCallPreservedMaskFromX0 ());
848- if (ZeroZA)
849- CommitZASave.addDef (AArch64::ZAB0, RegState::ImplicitDefine);
850- // Enable ZA (as ZA could have previously been in the OFF state).
851- BuildMI (MBB, MBBI, DL, TII->get (AArch64::MSRpstatesvcrImm1))
852- .addImm (AArch64SVCR::SVCRZA)
853- .addImm (1 );
833+ bool ZeroZA = AFI->getSMEFnAttrs ().isNewZA ();
834+ bool ZeroZT0 = AFI->getSMEFnAttrs ().isNewZT0 ();
835+ if (AFI->getSMEFnAttrs ().hasPrivateZAInterface ()) {
836+ // Get current TPIDR2_EL0.
837+ Register TPIDR2EL0 = MRI->createVirtualRegister (&AArch64::GPR64RegClass);
838+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::MRS))
839+ .addReg (TPIDR2EL0, RegState::Define)
840+ .addImm (AArch64SysReg::TPIDR2_EL0);
841+ // If TPIDR2_EL0 is non-zero, commit the lazy save.
842+ // NOTE: Functions that only use ZT0 don't need to zero ZA.
843+ auto CommitZASave =
844+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::CommitZASavePseudo))
845+ .addReg (TPIDR2EL0)
846+ .addImm (ZeroZA)
847+ .addImm (ZeroZT0)
848+ .addExternalSymbol (TLI->getLibcallName (RTLIB::SMEABI_TPIDR2_SAVE))
849+ .addRegMask (TRI->SMEABISupportRoutinesCallPreservedMaskFromX0 ());
850+ if (ZeroZA)
851+ CommitZASave.addDef (AArch64::ZAB0, RegState::ImplicitDefine);
852+ if (ZeroZT0)
853+ CommitZASave.addDef (AArch64::ZT0, RegState::ImplicitDefine);
854+ // Enable ZA (as ZA could have previously been in the OFF state).
855+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::MSRpstatesvcrImm1))
856+ .addImm (AArch64SVCR::SVCRZA)
857+ .addImm (1 );
858+ } else if (AFI->getSMEFnAttrs ().hasSharedZAInterface ()) {
859+ if (ZeroZA) {
860+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::ZERO_M))
861+ .addImm (ZERO_ALL_ZA_MASK)
862+ .addDef (AArch64::ZAB0, RegState::ImplicitDefine);
863+ }
864+ if (ZeroZT0) {
865+ DebugLoc DL = getDebugLoc (MBB, MBBI);
866+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::ZERO_T)).addDef (AArch64::ZT0);
867+ }
868+ }
854869}
855870
856871void MachineSMEABI::emitFullZASaveRestore (EmitContext &Context,
@@ -932,19 +947,19 @@ void MachineSMEABI::emitStateChange(EmitContext &Context,
932947 if (From == ZAState::ANY || To == ZAState::ANY)
933948 return ;
934949
935- // If we're exiting from the CALLER_DORMANT state that means this new ZA
936- // function did not touch ZA (so ZA was never turned on) .
937- if (From == ZAState::CALLER_DORMANT && To == ZAState::OFF)
950+ // If we're exiting from the ENTRY state that means that the function has not
951+ // used ZA, so in the case of private ZA/ZT0 functions we can omit any set up .
952+ if (From == ZAState::ENTRY && To == ZAState::OFF)
938953 return ;
939954
955+ SMEAttrs SMEFnAttrs = AFI->getSMEFnAttrs ();
956+
940957 // TODO: Avoid setting up the save buffer if there's no transition to
941958 // LOCAL_SAVED.
942- if (From == ZAState::CALLER_DORMANT) {
943- assert (AFI->getSMEFnAttrs ().hasPrivateZAInterface () &&
944- " CALLER_DORMANT state requires private ZA interface" );
959+ if (From == ZAState::ENTRY) {
945960 assert (&MBB == &MBB.getParent ()->front () &&
946- " CALLER_DORMANT state only valid in entry block" );
947- emitNewZAPrologue (MBB, MBB.getFirstNonPHI ());
961+ " ENTRY state only valid in entry block" );
962+ emitSMEPrologue (MBB, MBB.getFirstNonPHI ());
948963 if (To == ZAState::ACTIVE)
949964 return ; // Nothing more to do (ZA is active after the prologue).
950965
@@ -959,9 +974,9 @@ void MachineSMEABI::emitStateChange(EmitContext &Context,
959974 else if (From == ZAState::LOCAL_SAVED && To == ZAState::ACTIVE)
960975 emitZARestore (Context, MBB, InsertPt, PhysLiveRegs);
961976 else if (To == ZAState::OFF) {
962- assert (From != ZAState::CALLER_DORMANT &&
963- " CALLER_DORMANT to OFF should have already been handled" );
964- assert (!AFI-> getSMEFnAttrs () .hasAgnosticZAInterface () &&
977+ assert (From != ZAState::ENTRY &&
978+ " ENTRY to OFF should have already been handled" );
979+ assert (!SMEFnAttrs .hasAgnosticZAInterface () &&
965980 " Should not turn ZA off in agnostic ZA function" );
966981 emitZAOff (MBB, InsertPt, /* ClearTPIDR2=*/ From == ZAState::LOCAL_SAVED);
967982 } else {
0 commit comments