1 #include "Utils/AArch64SMEAttributes.h"
2 #include "llvm/AsmParser/Parser.h"
3 #include "llvm/IR/Function.h"
4 #include "llvm/IR/Module.h"
5 #include "llvm/Support/SourceMgr.h"
7 #include "gtest/gtest.h"
12 std::unique_ptr
<Module
> parseIR(const char *IR
) {
15 return parseAssemblyString(IR
, Err
, C
);
18 TEST(SMEAttributes
, Constructors
) {
21 ASSERT_TRUE(SA(*parseIR("declare void @foo()")->getFunction("foo"))
22 .hasNonStreamingInterfaceAndBody());
24 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")
26 .hasNonStreamingInterface());
28 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_enabled\"")
30 .hasStreamingInterface());
32 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_body\"")
37 SA(*parseIR("declare void @foo() \"aarch64_pstate_sm_compatible\"")
39 .hasStreamingCompatibleInterface());
41 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_shared\"")
45 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_shared\"")
47 .hasSharedZAInterface());
49 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_new\"")
53 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_pstate_za_preserved\"")
58 SA(*parseIR("declare void @foo() \"aarch64_in_zt0\"")->getFunction("foo"))
60 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_out_zt0\"")
63 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_inout_zt0\"")
66 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_preserves_zt0\"")
69 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_new_zt0\"")
73 // Invalid combinations.
74 EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled
| SA::SM_Compatible
),
75 "SM_Enabled and SM_Compatible are mutually exclusive");
76 EXPECT_DEBUG_DEATH(SA(SA::ZA_New
| SA::ZA_Shared
),
77 "ZA_New and ZA_Shared are mutually exclusive");
78 EXPECT_DEBUG_DEATH(SA(SA::ZA_New
| SA::ZA_Preserved
),
79 "ZA_New and ZA_Preserved are mutually exclusive");
81 // Test that the set() methods equally check validity.
82 EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled
).set(SA::SM_Compatible
),
83 "SM_Enabled and SM_Compatible are mutually exclusive");
84 EXPECT_DEBUG_DEATH(SA(SA::SM_Compatible
).set(SA::SM_Enabled
),
85 "SM_Enabled and SM_Compatible are mutually exclusive");
88 TEST(SMEAttributes
, Basics
) {
89 // Test PSTATE.SM interfaces.
90 ASSERT_TRUE(SA(SA::Normal
).hasNonStreamingInterfaceAndBody());
91 ASSERT_TRUE(SA(SA::SM_Enabled
).hasStreamingInterface());
92 ASSERT_TRUE(SA(SA::SM_Body
).hasStreamingBody());
93 ASSERT_TRUE(SA(SA::SM_Body
).hasNonStreamingInterface());
94 ASSERT_FALSE(SA(SA::SM_Body
).hasNonStreamingInterfaceAndBody());
95 ASSERT_FALSE(SA(SA::SM_Body
).hasStreamingInterface());
96 ASSERT_TRUE(SA(SA::SM_Compatible
).hasStreamingCompatibleInterface());
98 SA(SA::SM_Compatible
| SA::SM_Body
).hasStreamingCompatibleInterface());
99 ASSERT_TRUE(SA(SA::SM_Compatible
| SA::SM_Body
).hasStreamingBody());
100 ASSERT_FALSE(SA(SA::SM_Compatible
| SA::SM_Body
).hasNonStreamingInterface());
102 // Test PSTATE.ZA interfaces.
103 ASSERT_FALSE(SA(SA::ZA_Shared
).hasPrivateZAInterface());
104 ASSERT_TRUE(SA(SA::ZA_Shared
).hasSharedZAInterface());
105 ASSERT_TRUE(SA(SA::ZA_Shared
).sharesZA());
106 ASSERT_TRUE(SA(SA::ZA_Shared
).hasZAState());
107 ASSERT_FALSE(SA(SA::ZA_Shared
).preservesZA());
108 ASSERT_TRUE(SA(SA::ZA_Shared
| SA::ZA_Preserved
).preservesZA());
109 ASSERT_FALSE(SA(SA::ZA_Shared
).sharesZT0());
110 ASSERT_FALSE(SA(SA::ZA_Shared
).hasZT0State());
112 ASSERT_TRUE(SA(SA::ZA_New
).hasPrivateZAInterface());
113 ASSERT_FALSE(SA(SA::ZA_New
).hasSharedZAInterface());
114 ASSERT_TRUE(SA(SA::ZA_New
).hasNewZABody());
115 ASSERT_TRUE(SA(SA::ZA_New
).hasZAState());
116 ASSERT_FALSE(SA(SA::ZA_New
).preservesZA());
117 ASSERT_FALSE(SA(SA::ZA_New
).sharesZT0());
118 ASSERT_FALSE(SA(SA::ZA_New
).hasZT0State());
120 ASSERT_TRUE(SA(SA::Normal
).hasPrivateZAInterface());
121 ASSERT_FALSE(SA(SA::Normal
).hasSharedZAInterface());
122 ASSERT_FALSE(SA(SA::Normal
).hasNewZABody());
123 ASSERT_FALSE(SA(SA::Normal
).hasZAState());
124 ASSERT_FALSE(SA(SA::Normal
).preservesZA());
126 // Test ZT0 State interfaces
127 SA ZT0_In
= SA(SA::encodeZT0State(SA::StateValue::In
));
128 ASSERT_TRUE(ZT0_In
.isInZT0());
129 ASSERT_FALSE(ZT0_In
.isOutZT0());
130 ASSERT_FALSE(ZT0_In
.isInOutZT0());
131 ASSERT_FALSE(ZT0_In
.isPreservesZT0());
132 ASSERT_FALSE(ZT0_In
.isNewZT0());
133 ASSERT_TRUE(ZT0_In
.sharesZT0());
134 ASSERT_TRUE(ZT0_In
.hasZT0State());
135 ASSERT_TRUE(ZT0_In
.hasSharedZAInterface());
136 ASSERT_FALSE(ZT0_In
.hasPrivateZAInterface());
138 SA ZT0_Out
= SA(SA::encodeZT0State(SA::StateValue::Out
));
139 ASSERT_TRUE(ZT0_Out
.isOutZT0());
140 ASSERT_FALSE(ZT0_Out
.isInZT0());
141 ASSERT_FALSE(ZT0_Out
.isInOutZT0());
142 ASSERT_FALSE(ZT0_Out
.isPreservesZT0());
143 ASSERT_FALSE(ZT0_Out
.isNewZT0());
144 ASSERT_TRUE(ZT0_Out
.sharesZT0());
145 ASSERT_TRUE(ZT0_Out
.hasZT0State());
146 ASSERT_TRUE(ZT0_Out
.hasSharedZAInterface());
147 ASSERT_FALSE(ZT0_Out
.hasPrivateZAInterface());
149 SA ZT0_InOut
= SA(SA::encodeZT0State(SA::StateValue::InOut
));
150 ASSERT_TRUE(ZT0_InOut
.isInOutZT0());
151 ASSERT_FALSE(ZT0_InOut
.isInZT0());
152 ASSERT_FALSE(ZT0_InOut
.isOutZT0());
153 ASSERT_FALSE(ZT0_InOut
.isPreservesZT0());
154 ASSERT_FALSE(ZT0_InOut
.isNewZT0());
155 ASSERT_TRUE(ZT0_InOut
.sharesZT0());
156 ASSERT_TRUE(ZT0_InOut
.hasZT0State());
157 ASSERT_TRUE(ZT0_InOut
.hasSharedZAInterface());
158 ASSERT_FALSE(ZT0_InOut
.hasPrivateZAInterface());
160 SA ZT0_Preserved
= SA(SA::encodeZT0State(SA::StateValue::Preserved
));
161 ASSERT_TRUE(ZT0_Preserved
.isPreservesZT0());
162 ASSERT_FALSE(ZT0_Preserved
.isInZT0());
163 ASSERT_FALSE(ZT0_Preserved
.isOutZT0());
164 ASSERT_FALSE(ZT0_Preserved
.isInOutZT0());
165 ASSERT_FALSE(ZT0_Preserved
.isNewZT0());
166 ASSERT_TRUE(ZT0_Preserved
.sharesZT0());
167 ASSERT_TRUE(ZT0_Preserved
.hasZT0State());
168 ASSERT_TRUE(ZT0_Preserved
.hasSharedZAInterface());
169 ASSERT_FALSE(ZT0_Preserved
.hasPrivateZAInterface());
171 SA ZT0_New
= SA(SA::encodeZT0State(SA::StateValue::New
));
172 ASSERT_TRUE(ZT0_New
.isNewZT0());
173 ASSERT_FALSE(ZT0_New
.isInZT0());
174 ASSERT_FALSE(ZT0_New
.isOutZT0());
175 ASSERT_FALSE(ZT0_New
.isInOutZT0());
176 ASSERT_FALSE(ZT0_New
.isPreservesZT0());
177 ASSERT_FALSE(ZT0_New
.sharesZT0());
178 ASSERT_TRUE(ZT0_New
.hasZT0State());
179 ASSERT_FALSE(ZT0_New
.hasSharedZAInterface());
180 ASSERT_TRUE(ZT0_New
.hasPrivateZAInterface());
182 ASSERT_FALSE(SA(SA::Normal
).isInZT0());
183 ASSERT_FALSE(SA(SA::Normal
).isOutZT0());
184 ASSERT_FALSE(SA(SA::Normal
).isInOutZT0());
185 ASSERT_FALSE(SA(SA::Normal
).isPreservesZT0());
186 ASSERT_FALSE(SA(SA::Normal
).isNewZT0());
187 ASSERT_FALSE(SA(SA::Normal
).sharesZT0());
188 ASSERT_FALSE(SA(SA::Normal
).hasZT0State());
191 TEST(SMEAttributes
, Transitions
) {
193 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::Normal
)));
194 ASSERT_FALSE(SA(SA::Normal
).requiresPreservingZT0(SA(SA::Normal
)));
195 ASSERT_FALSE(SA(SA::Normal
).requiresDisablingZABeforeCall(SA(SA::Normal
)));
196 ASSERT_FALSE(SA(SA::Normal
).requiresEnablingZAAfterCall(SA(SA::Normal
)));
197 // Normal -> Normal + LocallyStreaming
198 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)));
200 // Normal -> Streaming
201 ASSERT_TRUE(SA(SA::Normal
).requiresSMChange(SA(SA::SM_Enabled
)));
202 // Normal -> Streaming + LocallyStreaming
204 SA(SA::Normal
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)));
206 // Normal -> Streaming-compatible
207 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::SM_Compatible
)));
208 // Normal -> Streaming-compatible + LocallyStreaming
210 SA(SA::Normal
).requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
212 // Streaming -> Normal
213 ASSERT_TRUE(SA(SA::SM_Enabled
).requiresSMChange(SA(SA::Normal
)));
214 // Streaming -> Normal + LocallyStreaming
216 SA(SA::SM_Enabled
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)));
218 // Streaming -> Streaming
219 ASSERT_FALSE(SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Enabled
)));
220 // Streaming -> Streaming + LocallyStreaming
222 SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)));
224 // Streaming -> Streaming-compatible
225 ASSERT_FALSE(SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Compatible
)));
226 // Streaming -> Streaming-compatible + LocallyStreaming
228 SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
230 // Streaming-compatible -> Normal
231 ASSERT_TRUE(SA(SA::SM_Compatible
).requiresSMChange(SA(SA::Normal
)));
233 SA(SA::SM_Compatible
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)));
235 // Streaming-compatible -> Streaming
236 ASSERT_TRUE(SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Enabled
)));
237 // Streaming-compatible -> Streaming + LocallyStreaming
239 SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)));
241 // Streaming-compatible -> Streaming-compatible
242 ASSERT_FALSE(SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Compatible
)));
243 // Streaming-compatible -> Streaming-compatible + LocallyStreaming
244 ASSERT_FALSE(SA(SA::SM_Compatible
)
245 .requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
247 SA Private_ZA
= SA(SA::Normal
);
248 SA ZA_Shared
= SA(SA::ZA_Shared
);
249 SA ZT0_Shared
= SA(SA::encodeZT0State(SA::StateValue::In
));
250 SA ZA_ZT0_Shared
= SA(SA::ZA_Shared
| SA::encodeZT0State(SA::StateValue::In
));
252 // Shared ZA -> Private ZA Interface
253 ASSERT_FALSE(ZA_Shared
.requiresDisablingZABeforeCall(Private_ZA
));
254 ASSERT_TRUE(ZA_Shared
.requiresEnablingZAAfterCall(Private_ZA
));
256 // Shared ZT0 -> Private ZA Interface
257 ASSERT_TRUE(ZT0_Shared
.requiresDisablingZABeforeCall(Private_ZA
));
258 ASSERT_TRUE(ZT0_Shared
.requiresPreservingZT0(Private_ZA
));
259 ASSERT_TRUE(ZT0_Shared
.requiresEnablingZAAfterCall(Private_ZA
));
261 // Shared ZA & ZT0 -> Private ZA Interface
262 ASSERT_FALSE(ZA_ZT0_Shared
.requiresDisablingZABeforeCall(Private_ZA
));
263 ASSERT_TRUE(ZA_ZT0_Shared
.requiresPreservingZT0(Private_ZA
));
264 ASSERT_TRUE(ZA_ZT0_Shared
.requiresEnablingZAAfterCall(Private_ZA
));
266 // Shared ZA -> Shared ZA Interface
267 ASSERT_FALSE(ZA_Shared
.requiresDisablingZABeforeCall(ZT0_Shared
));
268 ASSERT_FALSE(ZA_Shared
.requiresEnablingZAAfterCall(ZT0_Shared
));
270 // Shared ZT0 -> Shared ZA Interface
271 ASSERT_FALSE(ZT0_Shared
.requiresDisablingZABeforeCall(ZT0_Shared
));
272 ASSERT_FALSE(ZT0_Shared
.requiresPreservingZT0(ZT0_Shared
));
273 ASSERT_FALSE(ZT0_Shared
.requiresEnablingZAAfterCall(ZT0_Shared
));
275 // Shared ZA & ZT0 -> Shared ZA Interface
276 ASSERT_FALSE(ZA_ZT0_Shared
.requiresDisablingZABeforeCall(ZT0_Shared
));
277 ASSERT_FALSE(ZA_ZT0_Shared
.requiresPreservingZT0(ZT0_Shared
));
278 ASSERT_FALSE(ZA_ZT0_Shared
.requiresEnablingZAAfterCall(ZT0_Shared
));