@@ -574,6 +574,7 @@ class CXXNameMangler {
574574 static StringRef getCallingConvQualifierName (CallingConv CC);
575575 void mangleExtParameterInfo (FunctionProtoType::ExtParameterInfo info);
576576 void mangleExtFunctionInfo (const FunctionType *T);
577+ void mangleSMEAttrs (unsigned SMEAttrs);
577578 void mangleBareFunctionType (const FunctionProtoType *T, bool MangleReturnType,
578579 const FunctionDecl *FD = nullptr );
579580 void mangleNeonVectorType (const VectorType *T);
@@ -3532,6 +3533,69 @@ void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) {
35323533 // FIXME: noreturn
35333534}
35343535
3536+ enum class AAPCSBitmaskSME : unsigned {
3537+ ArmStreamingBit = 1 << 0 ,
3538+ ArmStreamingCompatibleBit = 1 << 1 ,
3539+ ArmAgnosticSMEZAStateBit = 1 << 2 ,
3540+ ZA_Shift = 3 ,
3541+ ZT0_Shift = 6 ,
3542+ NoState = 0b000 ,
3543+ ArmIn = 0b001 ,
3544+ ArmOut = 0b010 ,
3545+ ArmInOut = 0b011 ,
3546+ ArmPreserves = 0b100 ,
3547+ LLVM_MARK_AS_BITMASK_ENUM (/* LargestValue=*/ ArmPreserves << ZT0_Shift)
3548+ };
3549+
3550+ static AAPCSBitmaskSME encodeAAPCSZAState (unsigned SMEAttrs) {
3551+ switch (SMEAttrs) {
3552+ case FunctionType::ARM_None:
3553+ return AAPCSBitmaskSME::NoState;
3554+ case FunctionType::ARM_In:
3555+ return AAPCSBitmaskSME::ArmIn;
3556+ case FunctionType::ARM_Out:
3557+ return AAPCSBitmaskSME::ArmOut;
3558+ case FunctionType::ARM_InOut:
3559+ return AAPCSBitmaskSME::ArmInOut;
3560+ case FunctionType::ARM_Preserves:
3561+ return AAPCSBitmaskSME::ArmPreserves;
3562+ default :
3563+ llvm_unreachable (" Unrecognised SME attribute" );
3564+ }
3565+ }
3566+
3567+ // The mangling scheme for function types which have SME attributes is
3568+ // implemented as a "pseudo" template:
3569+ //
3570+ // '__SME_ATTRS<<normal_function_type>, <sme_state>>'
3571+ //
3572+ // Combining the function type with a bitmask representing the streaming and ZA
3573+ // properties of the function's interface.
3574+ //
3575+ // Mangling of SME keywords is described in more detail in the AArch64 ACLE:
3576+ // https://github.com/ARM-software/acle/blob/main/main/acle.md#c-mangling-of-sme-keywords
3577+ //
3578+ void CXXNameMangler::mangleSMEAttrs (unsigned SMEAttrs) {
3579+ if (!SMEAttrs)
3580+ return ;
3581+
3582+ AAPCSBitmaskSME Bitmask = AAPCSBitmaskSME (0 );
3583+ if (SMEAttrs & FunctionType::SME_PStateSMEnabledMask)
3584+ Bitmask |= AAPCSBitmaskSME::ArmStreamingBit;
3585+ else if (SMEAttrs & FunctionType::SME_PStateSMCompatibleMask)
3586+ Bitmask |= AAPCSBitmaskSME::ArmStreamingCompatibleBit;
3587+
3588+ // TODO: Must represent __arm_agnostic("sme_za_state")
3589+
3590+ Bitmask |= encodeAAPCSZAState (FunctionType::getArmZAState (SMEAttrs))
3591+ << AAPCSBitmaskSME::ZA_Shift;
3592+
3593+ Bitmask |= encodeAAPCSZAState (FunctionType::getArmZT0State (SMEAttrs))
3594+ << AAPCSBitmaskSME::ZT0_Shift;
3595+
3596+ Out << " Lj" << static_cast <unsigned >(Bitmask) << " EE" ;
3597+ }
3598+
35353599void
35363600CXXNameMangler::mangleExtParameterInfo (FunctionProtoType::ExtParameterInfo PI) {
35373601 // Vendor-specific qualifiers are emitted in reverse alphabetical order.
@@ -3569,6 +3633,11 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
35693633// <function-type> ::= [<CV-qualifiers>] F [Y]
35703634// <bare-function-type> [<ref-qualifier>] E
35713635void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3636+ unsigned SMEAttrs = T->getAArch64SMEAttributes ();
3637+
3638+ if (SMEAttrs)
3639+ Out << " 11__SME_ATTRSI" ;
3640+
35723641 mangleExtFunctionInfo (T);
35733642
35743643 // Mangle CV-qualifiers, if present. These are 'this' qualifiers,
@@ -3603,6 +3672,8 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
36033672 mangleRefQualifier (T->getRefQualifier ());
36043673
36053674 Out << ' E' ;
3675+
3676+ mangleSMEAttrs (SMEAttrs);
36063677}
36073678
36083679void CXXNameMangler::mangleType (const FunctionNoProtoType *T) {
0 commit comments