@@ -574,6 +574,7 @@ class CXXNameMangler {
574
574
static StringRef getCallingConvQualifierName (CallingConv CC);
575
575
void mangleExtParameterInfo (FunctionProtoType::ExtParameterInfo info);
576
576
void mangleExtFunctionInfo (const FunctionType *T);
577
+ void mangleSMEAttrs (unsigned SMEAttrs);
577
578
void mangleBareFunctionType (const FunctionProtoType *T, bool MangleReturnType,
578
579
const FunctionDecl *FD = nullptr );
579
580
void mangleNeonVectorType (const VectorType *T);
@@ -3532,6 +3533,69 @@ void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) {
3532
3533
// FIXME: noreturn
3533
3534
}
3534
3535
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
+
3535
3599
void
3536
3600
CXXNameMangler::mangleExtParameterInfo (FunctionProtoType::ExtParameterInfo PI) {
3537
3601
// Vendor-specific qualifiers are emitted in reverse alphabetical order.
@@ -3569,6 +3633,11 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
3569
3633
// <function-type> ::= [<CV-qualifiers>] F [Y]
3570
3634
// <bare-function-type> [<ref-qualifier>] E
3571
3635
void CXXNameMangler::mangleType (const FunctionProtoType *T) {
3636
+ unsigned SMEAttrs = T->getAArch64SMEAttributes ();
3637
+
3638
+ if (SMEAttrs)
3639
+ Out << " 11__SME_ATTRSI" ;
3640
+
3572
3641
mangleExtFunctionInfo (T);
3573
3642
3574
3643
// Mangle CV-qualifiers, if present. These are 'this' qualifiers,
@@ -3603,6 +3672,8 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
3603
3672
mangleRefQualifier (T->getRefQualifier ());
3604
3673
3605
3674
Out << ' E' ;
3675
+
3676
+ mangleSMEAttrs (SMEAttrs);
3606
3677
}
3607
3678
3608
3679
void CXXNameMangler::mangleType (const FunctionNoProtoType *T) {
0 commit comments