@@ -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);
@@ -395,9 +395,7 @@ FunctionInfo MachineSMEABI::collectNeededZAStates(SMEAttrs SMEFnAttrs) {
395395
396396 if (MBB.isEntryBlock ()) {
397397 // Entry block:
398- Block.FixedEntryState = SMEFnAttrs.hasPrivateZAInterface ()
399- ? ZAState::CALLER_DORMANT
400- : ZAState::ACTIVE;
398+ Block.FixedEntryState = ZAState::ENTRY;
401399 } else if (MBB.isEHPad ()) {
402400 // EH entry block:
403401 Block.FixedEntryState = ZAState::LOCAL_SAVED;
@@ -815,32 +813,49 @@ void MachineSMEABI::emitAllocateLazySaveBuffer(
815813 }
816814}
817815
818- void MachineSMEABI::emitNewZAPrologue (MachineBasicBlock &MBB,
819- MachineBasicBlock::iterator MBBI) {
816+ static constexpr unsigned ZERO_ALL_ZA_MASK = 0b11111111 ;
817+
818+ void MachineSMEABI::emitSMEPrologue (MachineBasicBlock &MBB,
819+ MachineBasicBlock::iterator MBBI) {
820820 auto *TLI = Subtarget->getTargetLowering ();
821821 DebugLoc DL = getDebugLoc (MBB, MBBI);
822822
823- // Get current TPIDR2_EL0.
824- Register TPIDR2EL0 = MRI->createVirtualRegister (&AArch64::GPR64RegClass);
825- BuildMI (MBB, MBBI, DL, TII->get (AArch64::MRS))
826- .addReg (TPIDR2EL0, RegState::Define)
827- .addImm (AArch64SysReg::TPIDR2_EL0);
828- // If TPIDR2_EL0 is non-zero, commit the lazy save.
829- // NOTE: Functions that only use ZT0 don't need to zero ZA.
830- bool ZeroZA = AFI->getSMEFnAttrs ().hasZAState ();
831- auto CommitZASave =
832- BuildMI (MBB, MBBI, DL, TII->get (AArch64::CommitZASavePseudo))
833- .addReg (TPIDR2EL0)
834- .addImm (ZeroZA ? 1 : 0 )
835- .addImm (/* ZeroZT0=*/ false )
836- .addExternalSymbol (TLI->getLibcallName (RTLIB::SMEABI_TPIDR2_SAVE))
837- .addRegMask (TRI->SMEABISupportRoutinesCallPreservedMaskFromX0 ());
838- if (ZeroZA)
839- CommitZASave.addDef (AArch64::ZAB0, RegState::ImplicitDefine);
840- // Enable ZA (as ZA could have previously been in the OFF state).
841- BuildMI (MBB, MBBI, DL, TII->get (AArch64::MSRpstatesvcrImm1))
842- .addImm (AArch64SVCR::SVCRZA)
843- .addImm (1 );
823+ bool ZeroZA = AFI->getSMEFnAttrs ().isNewZA ();
824+ bool ZeroZT0 = AFI->getSMEFnAttrs ().isNewZT0 ();
825+ if (AFI->getSMEFnAttrs ().hasPrivateZAInterface ()) {
826+ // Get current TPIDR2_EL0.
827+ Register TPIDR2EL0 = MRI->createVirtualRegister (&AArch64::GPR64RegClass);
828+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::MRS))
829+ .addReg (TPIDR2EL0, RegState::Define)
830+ .addImm (AArch64SysReg::TPIDR2_EL0);
831+ // If TPIDR2_EL0 is non-zero, commit the lazy save.
832+ // NOTE: Functions that only use ZT0 don't need to zero ZA.
833+ auto CommitZASave =
834+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::CommitZASavePseudo))
835+ .addReg (TPIDR2EL0)
836+ .addImm (ZeroZA)
837+ .addImm (ZeroZT0)
838+ .addExternalSymbol (TLI->getLibcallName (RTLIB::SMEABI_TPIDR2_SAVE))
839+ .addRegMask (TRI->SMEABISupportRoutinesCallPreservedMaskFromX0 ());
840+ if (ZeroZA)
841+ CommitZASave.addDef (AArch64::ZAB0, RegState::ImplicitDefine);
842+ if (ZeroZT0)
843+ CommitZASave.addDef (AArch64::ZT0, RegState::ImplicitDefine);
844+ // Enable ZA (as ZA could have previously been in the OFF state).
845+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::MSRpstatesvcrImm1))
846+ .addImm (AArch64SVCR::SVCRZA)
847+ .addImm (1 );
848+ } else if (AFI->getSMEFnAttrs ().hasSharedZAInterface ()) {
849+ if (ZeroZA) {
850+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::ZERO_M))
851+ .addImm (ZERO_ALL_ZA_MASK)
852+ .addDef (AArch64::ZAB0, RegState::ImplicitDefine);
853+ }
854+ if (ZeroZT0) {
855+ DebugLoc DL = getDebugLoc (MBB, MBBI);
856+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::ZERO_T)).addDef (AArch64::ZT0);
857+ }
858+ }
844859}
845860
846861void MachineSMEABI::emitFullZASaveRestore (EmitContext &Context,
@@ -922,19 +937,19 @@ void MachineSMEABI::emitStateChange(EmitContext &Context,
922937 if (From == ZAState::ANY || To == ZAState::ANY)
923938 return ;
924939
925- // If we're exiting from the CALLER_DORMANT state that means this new ZA
926- // function did not touch ZA (so ZA was never turned on) .
927- if (From == ZAState::CALLER_DORMANT && To == ZAState::OFF)
940+ // If we're exiting from the ENTRY state that means that the function has not
941+ // used ZA, so in the case of private ZA/ZT0 functions we can omit any set up .
942+ if (From == ZAState::ENTRY && To == ZAState::OFF)
928943 return ;
929944
945+ SMEAttrs SMEFnAttrs = AFI->getSMEFnAttrs ();
946+
930947 // TODO: Avoid setting up the save buffer if there's no transition to
931948 // LOCAL_SAVED.
932- if (From == ZAState::CALLER_DORMANT) {
933- assert (AFI->getSMEFnAttrs ().hasPrivateZAInterface () &&
934- " CALLER_DORMANT state requires private ZA interface" );
949+ if (From == ZAState::ENTRY) {
935950 assert (&MBB == &MBB.getParent ()->front () &&
936- " CALLER_DORMANT state only valid in entry block" );
937- emitNewZAPrologue (MBB, MBB.getFirstNonPHI ());
951+ " ENTRY state only valid in entry block" );
952+ emitSMEPrologue (MBB, MBB.getFirstNonPHI ());
938953 if (To == ZAState::ACTIVE)
939954 return ; // Nothing more to do (ZA is active after the prologue).
940955
@@ -949,9 +964,9 @@ void MachineSMEABI::emitStateChange(EmitContext &Context,
949964 else if (From == ZAState::LOCAL_SAVED && To == ZAState::ACTIVE)
950965 emitZARestore (Context, MBB, InsertPt, PhysLiveRegs);
951966 else if (To == ZAState::OFF) {
952- assert (From != ZAState::CALLER_DORMANT &&
953- " CALLER_DORMANT to OFF should have already been handled" );
954- assert (!AFI-> getSMEFnAttrs () .hasAgnosticZAInterface () &&
967+ assert (From != ZAState::ENTRY &&
968+ " ENTRY to OFF should have already been handled" );
969+ assert (!SMEFnAttrs .hasAgnosticZAInterface () &&
955970 " Should not turn ZA off in agnostic ZA function" );
956971 emitZAOff (MBB, InsertPt, /* ClearTPIDR2=*/ From == ZAState::LOCAL_SAVED);
957972 } else {
0 commit comments