[clang] [Clang][AArch64] Include SME attributes in the name mangling of function types (PR #114209)
Kerry McLaughlin via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 29 06:50:01 PST 2024
https://github.com/kmclaughlin-arm updated https://github.com/llvm/llvm-project/pull/114209
>From c62f48766cf24636045286449e98705a6a5bd76c Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Tue, 15 Oct 2024 15:22:56 +0000
Subject: [PATCH 1/5] [Clang][AArch64] Include SME attributes in the name
mangling of function types.
Similar to arm_sve_vector_bits, the mangling of function types is implemented as
a pseudo template if there are any SME attributes present, i.e.
__SME_ATTRS<normal_function_type, streaming_mode, za_state, zt0_state>
For example, the following function:
void f(svint8_t (*fn)() __arm_streaming) { fn(); }
is mangled as:
fP9__SME_ATTRSIFu10__SVInt8_tELj1ELj0ELj0EE
See https://github.com/ARM-software/abi-aa/pull/290
---
clang/lib/AST/ItaniumMangle.cpp | 41 ++++++++++++
.../CodeGenCXX/aarch64-mangle-sme-atts.cpp | 65 +++++++++++++++++++
2 files changed, 106 insertions(+)
create mode 100644 clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 27a993a631dae9c..e3e94193d9cce10 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -574,6 +574,7 @@ class CXXNameMangler {
static StringRef getCallingConvQualifierName(CallingConv CC);
void mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo info);
void mangleExtFunctionInfo(const FunctionType *T);
+ void mangleSMEAttrs(unsigned SMEAttrs);
void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType,
const FunctionDecl *FD = nullptr);
void mangleNeonVectorType(const VectorType *T);
@@ -3532,6 +3533,39 @@ void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) {
// FIXME: noreturn
}
+bool hasSharedState(unsigned SMEAttrs) {
+ switch (SMEAttrs) {
+ case FunctionType::ARM_In:
+ case FunctionType::ARM_Out:
+ case FunctionType::ARM_InOut:
+ case FunctionType::ARM_Preserves:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void CXXNameMangler::mangleSMEAttrs(unsigned SMEAttrs) {
+ if (!SMEAttrs)
+ return;
+
+ // Streaming Mode
+ if (SMEAttrs & FunctionType::SME_PStateSMEnabledMask)
+ Out << "Lj1E";
+ else if (SMEAttrs & FunctionType::SME_PStateSMCompatibleMask)
+ Out << "Lj2E";
+ else
+ Out << "Lj0E";
+
+ // ZA & ZT0 State
+ Out << (hasSharedState(FunctionType::getArmZAState(SMEAttrs)) ? "Lj1E"
+ : "Lj0E");
+ Out << (hasSharedState(FunctionType::getArmZT0State(SMEAttrs)) ? "Lj1E"
+ : "Lj0E");
+
+ return;
+}
+
void
CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
// Vendor-specific qualifiers are emitted in reverse alphabetical order.
@@ -3569,6 +3603,11 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
// <function-type> ::= [<CV-qualifiers>] F [Y]
// <bare-function-type> [<ref-qualifier>] E
void CXXNameMangler::mangleType(const FunctionProtoType *T) {
+ unsigned SMEAttrs = T->getAArch64SMEAttributes();
+
+ if (SMEAttrs)
+ Out << "11__SME_ATTRSI";
+
mangleExtFunctionInfo(T);
// Mangle CV-qualifiers, if present. These are 'this' qualifiers,
@@ -3602,6 +3641,8 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
// Mangle the ref-qualifier, if present.
mangleRefQualifier(T->getRefQualifier());
+ mangleSMEAttrs(SMEAttrs);
+
Out << 'E';
}
diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp
new file mode 100644
index 000000000000000..16d4111cdfaaa16
--- /dev/null
+++ b/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme -target-feature +sme2 %s -emit-llvm -o - | FileCheck %s
+
+typedef __attribute__((neon_vector_type(2))) int int32x2_t;
+
+//
+// Streaming-Mode Attributes
+//
+
+// CHECK: define dso_local void @_Z12fn_streamingP11__SME_ATTRSIFvvLj1ELj0ELj0EE(
+void fn_streaming(void (*foo)() __arm_streaming) { foo(); }
+
+// CHECK: define dso_local void @_Z12fn_streamingP11__SME_ATTRSIFivLj2ELj0ELj0EE(
+void fn_streaming(int (*foo)() __arm_streaming_compatible) { foo(); }
+
+//
+// ZA Attributes
+//
+
+// CHECK: define dso_local void @_Z15fn_za_preservedP11__SME_ATTRSIF11__Int32x2_tvLj0ELj1ELj0EE(
+__arm_new("za") void fn_za_preserved(int32x2_t (*foo)() __arm_preserves("za")) { foo(); }
+
+// CHECK: define dso_local void @_Z8fn_za_inP11__SME_ATTRSIFvu13__SVFloat64_tLj0ELj1ELj0EES_(
+__arm_new("za") void fn_za_in(void (*foo)(__SVFloat64_t) __arm_in("za"), __SVFloat64_t x) { foo(x); }
+
+// CHECK: define dso_local noundef i32 @_Z9fn_za_outP11__SME_ATTRSIFivLj0ELj1ELj0EE(
+__arm_new("za") int fn_za_out(int (*foo)() __arm_out("za")) { return foo(); }
+
+// CHECK: define dso_local void @_Z11fn_za_inoutP11__SME_ATTRSIFvvLj0ELj1ELj0EE(
+__arm_new("za") void fn_za_inout(void (*foo)() __arm_inout("za")) { foo(); }
+
+
+//
+// ZT0 Attributes
+//
+
+// CHECK: define dso_local void @_Z16fn_zt0_preservedP11__SME_ATTRSIFivLj0ELj0ELj1EE(
+__arm_new("zt0") void fn_zt0_preserved(int (*foo)() __arm_preserves("zt0")) { foo(); }
+
+// CHECK: define dso_local void @_Z9fn_zt0_inP11__SME_ATTRSIFivLj0ELj0ELj1EE(
+__arm_new("zt0") void fn_zt0_in(int (*foo)() __arm_in("zt0")) { foo(); }
+
+// CHECK: define dso_local void @_Z10fn_zt0_outP11__SME_ATTRSIFivLj0ELj0ELj1EE(
+__arm_new("zt0") void fn_zt0_out(int (*foo)() __arm_out("zt0")) { foo(); }
+
+// CHECK: define dso_local void @_Z12fn_zt0_inoutP11__SME_ATTRSIFivLj0ELj0ELj1EE(
+__arm_new("zt0") void fn_zt0_inout(int (*foo)() __arm_inout("zt0")) { foo(); }
+
+//
+// No SME Attributes
+//
+
+// CHECK: define dso_local void @_Z12no_sme_attrsPFvvE(
+void no_sme_attrs(void (*foo)()) { foo(); }
+
+// CHECK: define dso_local void @_Z24locally_streaming_callerPFvvE(
+__arm_locally_streaming void locally_streaming_caller(void (*foo)()) { foo(); }
+
+// CHECK: define dso_local void @_Z16streaming_callerv(
+void streaming_caller() __arm_streaming {}
+
+// CHECK: define dso_local void @_Z16za_shared_callerv(
+void za_shared_caller() __arm_in("za") {}
+
+// CHECK: define dso_local void @_Z17zt0_shared_callerv(
+void zt0_shared_caller() __arm_out("zt0") {}
>From 153c45ef119302024b718ee1a6db8ec08472a243 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Mon, 4 Nov 2024 13:23:07 +0000
Subject: [PATCH 2/5] - Attributes are now encoded as one bitmask, with each of
the attributes represented separately. - Removed hasSharedState.
---
clang/lib/AST/ItaniumMangle.cpp | 57 ++++++++++++++-----
.../CodeGenCXX/aarch64-mangle-sme-atts.cpp | 31 ++++++----
2 files changed, 63 insertions(+), 25 deletions(-)
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index e3e94193d9cce10..d0abfb75c60e1c6 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3533,35 +3533,64 @@ void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) {
// FIXME: noreturn
}
-bool hasSharedState(unsigned SMEAttrs) {
+unsigned getZAState(unsigned SMEAttrs) {
switch (SMEAttrs) {
case FunctionType::ARM_In:
+ return 1;
case FunctionType::ARM_Out:
+ return 2;
case FunctionType::ARM_InOut:
+ return 3;
case FunctionType::ARM_Preserves:
- return true;
+ return 4;
default:
- return false;
+ return 0;
}
}
+// The mangling scheme for function types which have SME attributes is implemented as
+// a "pseudo" template:
+//
+// '__SME_ATTRS<<normal_function_type>, <sme_state>>'
+//
+// Combining the function type with a bitmask representing the streaming and ZA properties
+// of the function's interface. The bits of sme_state are defined as follows:
+// 0: Streaming Mode
+// 1: Streaming Compatible
+// 2: ZA Agnostic
+// 3-5: ZA State
+// 6-8: ZT0 State
+// 9-63: 0, reserved for future type attributes.
+//
+// For example:
+// void f(svint8_t (*fn)() __arm_streaming_compatible __arm_inout("za")) { fn(); }
+//
+// The function fn is described as '__SME_ATTRS<Fu10__SVInt8_tvE, 26u>' and mangled as:
+//
+// "11__SME_ATTRSI" + function type mangling + "Lj" + bitmask + "EE"
+//
+// i.e. "11__SME_ATTRSIFu10__SVInt8_tvELj26EE"
+//
void CXXNameMangler::mangleSMEAttrs(unsigned SMEAttrs) {
if (!SMEAttrs)
return;
// Streaming Mode
+ unsigned Bitmask = 0;
if (SMEAttrs & FunctionType::SME_PStateSMEnabledMask)
- Out << "Lj1E";
+ Bitmask |= 1;
else if (SMEAttrs & FunctionType::SME_PStateSMCompatibleMask)
- Out << "Lj2E";
- else
- Out << "Lj0E";
+ Bitmask |= 1 << 1;
+
+ // TODO: Must represent __arm_agnostic("sme_za_state")
+
+ // ZA-State
+ Bitmask |= getZAState(FunctionType::getArmZAState(SMEAttrs)) << 3;
+
+ // ZT0 State
+ Bitmask |= getZAState(FunctionType::getArmZT0State(SMEAttrs)) << 6;
- // ZA & ZT0 State
- Out << (hasSharedState(FunctionType::getArmZAState(SMEAttrs)) ? "Lj1E"
- : "Lj0E");
- Out << (hasSharedState(FunctionType::getArmZT0State(SMEAttrs)) ? "Lj1E"
- : "Lj0E");
+ Out << "Lj" << Bitmask << "EE";
return;
}
@@ -3641,9 +3670,9 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
// Mangle the ref-qualifier, if present.
mangleRefQualifier(T->getRefQualifier());
- mangleSMEAttrs(SMEAttrs);
-
Out << 'E';
+
+ mangleSMEAttrs(SMEAttrs);
}
void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp
index 16d4111cdfaaa16..09db59ac621a223 100644
--- a/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp
+++ b/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp
@@ -6,26 +6,26 @@ typedef __attribute__((neon_vector_type(2))) int int32x2_t;
// Streaming-Mode Attributes
//
-// CHECK: define dso_local void @_Z12fn_streamingP11__SME_ATTRSIFvvLj1ELj0ELj0EE(
+// CHECK: define dso_local void @_Z12fn_streamingP11__SME_ATTRSIFvvELj1EE
void fn_streaming(void (*foo)() __arm_streaming) { foo(); }
-// CHECK: define dso_local void @_Z12fn_streamingP11__SME_ATTRSIFivLj2ELj0ELj0EE(
-void fn_streaming(int (*foo)() __arm_streaming_compatible) { foo(); }
+// CHECK: define dso_local void @_Z23fn_streaming_compatibleP11__SME_ATTRSIFivELj2EE(
+void fn_streaming_compatible(int (*foo)() __arm_streaming_compatible) { foo(); }
//
// ZA Attributes
//
-// CHECK: define dso_local void @_Z15fn_za_preservedP11__SME_ATTRSIF11__Int32x2_tvLj0ELj1ELj0EE(
+// CHECK: define dso_local void @_Z15fn_za_preservedP11__SME_ATTRSIF11__Int32x2_tvELj32EE(
__arm_new("za") void fn_za_preserved(int32x2_t (*foo)() __arm_preserves("za")) { foo(); }
-// CHECK: define dso_local void @_Z8fn_za_inP11__SME_ATTRSIFvu13__SVFloat64_tLj0ELj1ELj0EES_(
+// CHECK: define dso_local void @_Z8fn_za_inP11__SME_ATTRSIFvu13__SVFloat64_tELj8EES_(
__arm_new("za") void fn_za_in(void (*foo)(__SVFloat64_t) __arm_in("za"), __SVFloat64_t x) { foo(x); }
-// CHECK: define dso_local noundef i32 @_Z9fn_za_outP11__SME_ATTRSIFivLj0ELj1ELj0EE(
+// CHECK: define dso_local noundef i32 @_Z9fn_za_outP11__SME_ATTRSIFivELj16EE(
__arm_new("za") int fn_za_out(int (*foo)() __arm_out("za")) { return foo(); }
-// CHECK: define dso_local void @_Z11fn_za_inoutP11__SME_ATTRSIFvvLj0ELj1ELj0EE(
+// CHECK: define dso_local void @_Z11fn_za_inoutP11__SME_ATTRSIFvvELj24EE(
__arm_new("za") void fn_za_inout(void (*foo)() __arm_inout("za")) { foo(); }
@@ -33,18 +33,27 @@ __arm_new("za") void fn_za_inout(void (*foo)() __arm_inout("za")) { foo(); }
// ZT0 Attributes
//
-// CHECK: define dso_local void @_Z16fn_zt0_preservedP11__SME_ATTRSIFivLj0ELj0ELj1EE(
+// CHECK: define dso_local void @_Z16fn_zt0_preservedP11__SME_ATTRSIFivELj256EE(
__arm_new("zt0") void fn_zt0_preserved(int (*foo)() __arm_preserves("zt0")) { foo(); }
-// CHECK: define dso_local void @_Z9fn_zt0_inP11__SME_ATTRSIFivLj0ELj0ELj1EE(
+// CHECK: define dso_local void @_Z9fn_zt0_inP11__SME_ATTRSIFivELj64EE(
__arm_new("zt0") void fn_zt0_in(int (*foo)() __arm_in("zt0")) { foo(); }
-// CHECK: define dso_local void @_Z10fn_zt0_outP11__SME_ATTRSIFivLj0ELj0ELj1EE(
+// CHECK: define dso_local void @_Z10fn_zt0_outP11__SME_ATTRSIFivELj128EE(
__arm_new("zt0") void fn_zt0_out(int (*foo)() __arm_out("zt0")) { foo(); }
-// CHECK: define dso_local void @_Z12fn_zt0_inoutP11__SME_ATTRSIFivLj0ELj0ELj1EE(
+// CHECK: define dso_local void @_Z12fn_zt0_inoutP11__SME_ATTRSIFivELj192EE(
__arm_new("zt0") void fn_zt0_inout(int (*foo)() __arm_inout("zt0")) { foo(); }
+//
+// Streaming-mode, ZA & ZT0 Attributes
+//
+
+// CHECK: define dso_local void @_Z17fn_all_attr_typesP11__SME_ATTRSIFivELj282EE(
+__arm_new("za") __arm_new("zt0")
+void fn_all_attr_types(int (*foo)() __arm_streaming_compatible __arm_inout("za") __arm_preserves("zt0"))
+{ foo(); }
+
//
// No SME Attributes
//
>From cada212f1c1f0dc6f64f3bf4da94402e93c7292b Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Mon, 25 Nov 2024 16:27:16 +0000
Subject: [PATCH 3/5] - Added SMEState enum - Renamed getZAState ->
encodeZAState - Added llvm_unreachable to encodeZAState - Added a link to the
AAPCS in the comment above mangleSMEAttrs
---
clang/lib/AST/ItaniumMangle.cpp | 66 ++++++++++++++++++---------------
1 file changed, 36 insertions(+), 30 deletions(-)
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index d0abfb75c60e1c6..af8f576a3960bb2 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3533,62 +3533,68 @@ void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) {
// FIXME: noreturn
}
-unsigned getZAState(unsigned SMEAttrs) {
+enum SMEState {
+ Normal = 0,
+ SM_Enabled = 1 << 0,
+ SM_Compatible = 1 << 1,
+ ZA_Agnostic = 1 << 2,
+ ZA_Shift = 3,
+ ZT0_Shift = 6,
+ None = 0b000,
+ In = 0b001,
+ Out = 0b010,
+ InOut = 0b011,
+ Preserves = 0b100
+};
+
+unsigned encodeZAState(unsigned SMEAttrs) {
switch (SMEAttrs) {
+ case FunctionType::ARM_None:
+ return SMEState::None;
case FunctionType::ARM_In:
- return 1;
+ return SMEState::In;
case FunctionType::ARM_Out:
- return 2;
+ return SMEState::Out;
case FunctionType::ARM_InOut:
- return 3;
+ return SMEState::InOut;
case FunctionType::ARM_Preserves:
- return 4;
- default:
- return 0;
+ return SMEState::Preserves;
}
+ llvm_unreachable("Unrecognised SME attribute");
}
-// The mangling scheme for function types which have SME attributes is implemented as
-// a "pseudo" template:
+// As described in the AArch64 ACLE, the mangling scheme for function types
+// which have SME attributes is implemented as a "pseudo" template:
//
// '__SME_ATTRS<<normal_function_type>, <sme_state>>'
//
-// Combining the function type with a bitmask representing the streaming and ZA properties
-// of the function's interface. The bits of sme_state are defined as follows:
-// 0: Streaming Mode
-// 1: Streaming Compatible
-// 2: ZA Agnostic
-// 3-5: ZA State
-// 6-8: ZT0 State
-// 9-63: 0, reserved for future type attributes.
-//
-// For example:
-// void f(svint8_t (*fn)() __arm_streaming_compatible __arm_inout("za")) { fn(); }
-//
-// The function fn is described as '__SME_ATTRS<Fu10__SVInt8_tvE, 26u>' and mangled as:
+// Combining the function type with a bitmask representing the streaming and ZA
+// properties of the function's interface.
//
-// "11__SME_ATTRSI" + function type mangling + "Lj" + bitmask + "EE"
-//
-// i.e. "11__SME_ATTRSIFu10__SVInt8_tvELj26EE"
+// The mangling scheme is otherwise defined in the appendices to the Procedure
+// Call Standard for the Arm Architecture, see
+// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#appendix-c-mangling
//
void CXXNameMangler::mangleSMEAttrs(unsigned SMEAttrs) {
if (!SMEAttrs)
return;
// Streaming Mode
- unsigned Bitmask = 0;
+ unsigned Bitmask = SMEState::Normal;
if (SMEAttrs & FunctionType::SME_PStateSMEnabledMask)
- Bitmask |= 1;
+ Bitmask |= SMEState::SM_Enabled;
else if (SMEAttrs & FunctionType::SME_PStateSMCompatibleMask)
- Bitmask |= 1 << 1;
+ Bitmask |= SMEState::SM_Compatible;
// TODO: Must represent __arm_agnostic("sme_za_state")
// ZA-State
- Bitmask |= getZAState(FunctionType::getArmZAState(SMEAttrs)) << 3;
+ Bitmask |= encodeZAState(FunctionType::getArmZAState(SMEAttrs))
+ << SMEState::ZA_Shift;
// ZT0 State
- Bitmask |= getZAState(FunctionType::getArmZT0State(SMEAttrs)) << 6;
+ Bitmask |= encodeZAState(FunctionType::getArmZT0State(SMEAttrs))
+ << SMEState::ZT0_Shift;
Out << "Lj" << Bitmask << "EE";
>From b264d84e1c362b7e0ad37839c968a523ed6f13b9 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Tue, 26 Nov 2024 13:38:15 +0000
Subject: [PATCH 4/5] - Changed name of SMEState & changed to enum class -
Renamed encodeZAState -> encodeAAPCSZAState - Removed Normal from SMEState
enum - Added a link to the relevant section of the AArch64 ACLE doc
---
clang/lib/AST/ItaniumMangle.cpp | 62 +++++++++++++++------------------
1 file changed, 29 insertions(+), 33 deletions(-)
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index af8f576a3960bb2..e7f82e7b0050d44 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3533,72 +3533,68 @@ void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) {
// FIXME: noreturn
}
-enum SMEState {
- Normal = 0,
- SM_Enabled = 1 << 0,
- SM_Compatible = 1 << 1,
- ZA_Agnostic = 1 << 2,
+enum class AAPCSBitmaskSME : unsigned {
+ ArmStreamingBit = 1 << 0,
+ ArmStreamingCompatibleBit = 1 << 1,
+ ArmAgnosticSMEZAStateBit = 1 << 2,
ZA_Shift = 3,
ZT0_Shift = 6,
- None = 0b000,
- In = 0b001,
- Out = 0b010,
- InOut = 0b011,
- Preserves = 0b100
+ NoState = 0b000,
+ ArmIn = 0b001,
+ ArmOut = 0b010,
+ ArmInOut = 0b011,
+ ArmPreserves = 0b100
};
-unsigned encodeZAState(unsigned SMEAttrs) {
+static unsigned encodeAAPCSZAState(unsigned SMEAttrs) {
switch (SMEAttrs) {
case FunctionType::ARM_None:
- return SMEState::None;
+ return static_cast<unsigned>(AAPCSBitmaskSME::NoState);
case FunctionType::ARM_In:
- return SMEState::In;
+ return static_cast<unsigned>(AAPCSBitmaskSME::ArmIn);
case FunctionType::ARM_Out:
- return SMEState::Out;
+ return static_cast<unsigned>(AAPCSBitmaskSME::ArmOut);
case FunctionType::ARM_InOut:
- return SMEState::InOut;
+ return static_cast<unsigned>(AAPCSBitmaskSME::ArmInOut);
case FunctionType::ARM_Preserves:
- return SMEState::Preserves;
+ return static_cast<unsigned>(AAPCSBitmaskSME::ArmPreserves);
+ default:
+ llvm_unreachable("Unrecognised SME attribute");
}
- llvm_unreachable("Unrecognised SME attribute");
}
-// As described in the AArch64 ACLE, the mangling scheme for function types
-// which have SME attributes is implemented as a "pseudo" template:
+// The mangling scheme for function types which have SME attributes is
+// implemented as a "pseudo" template:
//
// '__SME_ATTRS<<normal_function_type>, <sme_state>>'
//
// Combining the function type with a bitmask representing the streaming and ZA
// properties of the function's interface.
//
-// The mangling scheme is otherwise defined in the appendices to the Procedure
-// Call Standard for the Arm Architecture, see
-// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#appendix-c-mangling
+// Mangling of SME keywords is described in more detail in the AArch64 ACLE:
+// https://github.com/ARM-software/acle/blob/main/main/acle.md#c-mangling-of-sme-keywords
//
void CXXNameMangler::mangleSMEAttrs(unsigned SMEAttrs) {
if (!SMEAttrs)
return;
// Streaming Mode
- unsigned Bitmask = SMEState::Normal;
+ unsigned Bitmask = 0;
if (SMEAttrs & FunctionType::SME_PStateSMEnabledMask)
- Bitmask |= SMEState::SM_Enabled;
+ Bitmask |= static_cast<unsigned>(AAPCSBitmaskSME::ArmStreamingBit);
else if (SMEAttrs & FunctionType::SME_PStateSMCompatibleMask)
- Bitmask |= SMEState::SM_Compatible;
+ Bitmask |=
+ static_cast<unsigned>(AAPCSBitmaskSME::ArmStreamingCompatibleBit);
// TODO: Must represent __arm_agnostic("sme_za_state")
- // ZA-State
- Bitmask |= encodeZAState(FunctionType::getArmZAState(SMEAttrs))
- << SMEState::ZA_Shift;
+ Bitmask |= encodeAAPCSZAState(FunctionType::getArmZAState(SMEAttrs))
+ << static_cast<unsigned>(AAPCSBitmaskSME::ZA_Shift);
- // ZT0 State
- Bitmask |= encodeZAState(FunctionType::getArmZT0State(SMEAttrs))
- << SMEState::ZT0_Shift;
+ Bitmask |= encodeAAPCSZAState(FunctionType::getArmZT0State(SMEAttrs))
+ << static_cast<unsigned>(AAPCSBitmaskSME::ZT0_Shift);
Out << "Lj" << Bitmask << "EE";
-
- return;
}
void
>From e84a78147d86e570e99a10babb09215a627f3370 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Fri, 29 Nov 2024 14:29:56 +0000
Subject: [PATCH 5/5] - Added LLVM_MARK_AS_BITMASK_ENUM & removed static_casts
from encodeAAPCSZAState
---
clang/lib/AST/ItaniumMangle.cpp | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index e7f82e7b0050d44..cbca5eba36f1747 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3543,21 +3543,22 @@ enum class AAPCSBitmaskSME : unsigned {
ArmIn = 0b001,
ArmOut = 0b010,
ArmInOut = 0b011,
- ArmPreserves = 0b100
+ ArmPreserves = 0b100,
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/ArmPreserves)
};
-static unsigned encodeAAPCSZAState(unsigned SMEAttrs) {
+static AAPCSBitmaskSME encodeAAPCSZAState(unsigned SMEAttrs) {
switch (SMEAttrs) {
case FunctionType::ARM_None:
- return static_cast<unsigned>(AAPCSBitmaskSME::NoState);
+ return AAPCSBitmaskSME::NoState;
case FunctionType::ARM_In:
- return static_cast<unsigned>(AAPCSBitmaskSME::ArmIn);
+ return AAPCSBitmaskSME::ArmIn;
case FunctionType::ARM_Out:
- return static_cast<unsigned>(AAPCSBitmaskSME::ArmOut);
+ return AAPCSBitmaskSME::ArmOut;
case FunctionType::ARM_InOut:
- return static_cast<unsigned>(AAPCSBitmaskSME::ArmInOut);
+ return AAPCSBitmaskSME::ArmInOut;
case FunctionType::ARM_Preserves:
- return static_cast<unsigned>(AAPCSBitmaskSME::ArmPreserves);
+ return AAPCSBitmaskSME::ArmPreserves;
default:
llvm_unreachable("Unrecognised SME attribute");
}
@@ -3578,7 +3579,6 @@ void CXXNameMangler::mangleSMEAttrs(unsigned SMEAttrs) {
if (!SMEAttrs)
return;
- // Streaming Mode
unsigned Bitmask = 0;
if (SMEAttrs & FunctionType::SME_PStateSMEnabledMask)
Bitmask |= static_cast<unsigned>(AAPCSBitmaskSME::ArmStreamingBit);
@@ -3588,11 +3588,13 @@ void CXXNameMangler::mangleSMEAttrs(unsigned SMEAttrs) {
// TODO: Must represent __arm_agnostic("sme_za_state")
- Bitmask |= encodeAAPCSZAState(FunctionType::getArmZAState(SMEAttrs))
- << static_cast<unsigned>(AAPCSBitmaskSME::ZA_Shift);
+ Bitmask |= static_cast<unsigned>(
+ encodeAAPCSZAState(FunctionType::getArmZAState(SMEAttrs))
+ << AAPCSBitmaskSME::ZA_Shift);
- Bitmask |= encodeAAPCSZAState(FunctionType::getArmZT0State(SMEAttrs))
- << static_cast<unsigned>(AAPCSBitmaskSME::ZT0_Shift);
+ Bitmask |= static_cast<unsigned>(
+ encodeAAPCSZAState(FunctionType::getArmZT0State(SMEAttrs))
+ << AAPCSBitmaskSME::ZT0_Shift);
Out << "Lj" << Bitmask << "EE";
}
More information about the cfe-commits
mailing list