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());
42 SA(*parseIR("declare void @foo() \"aarch64_in_za\"")->getFunction("foo"))
45 SA(*parseIR("declare void @foo() \"aarch64_out_za\"")->getFunction("foo"))
47 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_inout_za\"")
50 ASSERT_TRUE(SA(*parseIR("declare void @foo() \"aarch64_preserves_za\"")
54 SA(*parseIR("declare void @foo() \"aarch64_new_za\"")->getFunction("foo"))
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");
77 // Test that the set() methods equally check validity.
78 EXPECT_DEBUG_DEATH(SA(SA::SM_Enabled
).set(SA::SM_Compatible
),
79 "SM_Enabled and SM_Compatible are mutually exclusive");
80 EXPECT_DEBUG_DEATH(SA(SA::SM_Compatible
).set(SA::SM_Enabled
),
81 "SM_Enabled and SM_Compatible are mutually exclusive");
84 TEST(SMEAttributes
, Basics
) {
85 // Test PSTATE.SM interfaces.
86 ASSERT_TRUE(SA(SA::Normal
).hasNonStreamingInterfaceAndBody());
87 ASSERT_TRUE(SA(SA::SM_Enabled
).hasStreamingInterface());
88 ASSERT_TRUE(SA(SA::SM_Body
).hasStreamingBody());
89 ASSERT_TRUE(SA(SA::SM_Body
).hasNonStreamingInterface());
90 ASSERT_FALSE(SA(SA::SM_Body
).hasNonStreamingInterfaceAndBody());
91 ASSERT_FALSE(SA(SA::SM_Body
).hasStreamingInterface());
92 ASSERT_TRUE(SA(SA::SM_Compatible
).hasStreamingCompatibleInterface());
94 SA(SA::SM_Compatible
| SA::SM_Body
).hasStreamingCompatibleInterface());
95 ASSERT_TRUE(SA(SA::SM_Compatible
| SA::SM_Body
).hasStreamingBody());
96 ASSERT_FALSE(SA(SA::SM_Compatible
| SA::SM_Body
).hasNonStreamingInterface());
98 // Test ZA State interfaces
99 SA ZA_In
= SA(SA::encodeZAState(SA::StateValue::In
));
100 ASSERT_TRUE(ZA_In
.isInZA());
101 ASSERT_FALSE(ZA_In
.isOutZA());
102 ASSERT_FALSE(ZA_In
.isInOutZA());
103 ASSERT_FALSE(ZA_In
.isPreservesZA());
104 ASSERT_FALSE(ZA_In
.isNewZA());
105 ASSERT_TRUE(ZA_In
.sharesZA());
106 ASSERT_TRUE(ZA_In
.hasZAState());
107 ASSERT_TRUE(ZA_In
.hasSharedZAInterface());
108 ASSERT_FALSE(ZA_In
.hasPrivateZAInterface());
110 SA ZA_Out
= SA(SA::encodeZAState(SA::StateValue::Out
));
111 ASSERT_TRUE(ZA_Out
.isOutZA());
112 ASSERT_FALSE(ZA_Out
.isInZA());
113 ASSERT_FALSE(ZA_Out
.isInOutZA());
114 ASSERT_FALSE(ZA_Out
.isPreservesZA());
115 ASSERT_FALSE(ZA_Out
.isNewZA());
116 ASSERT_TRUE(ZA_Out
.sharesZA());
117 ASSERT_TRUE(ZA_Out
.hasZAState());
118 ASSERT_TRUE(ZA_Out
.hasSharedZAInterface());
119 ASSERT_FALSE(ZA_Out
.hasPrivateZAInterface());
121 SA ZA_InOut
= SA(SA::encodeZAState(SA::StateValue::InOut
));
122 ASSERT_TRUE(ZA_InOut
.isInOutZA());
123 ASSERT_FALSE(ZA_InOut
.isInZA());
124 ASSERT_FALSE(ZA_InOut
.isOutZA());
125 ASSERT_FALSE(ZA_InOut
.isPreservesZA());
126 ASSERT_FALSE(ZA_InOut
.isNewZA());
127 ASSERT_TRUE(ZA_InOut
.sharesZA());
128 ASSERT_TRUE(ZA_InOut
.hasZAState());
129 ASSERT_TRUE(ZA_InOut
.hasSharedZAInterface());
130 ASSERT_FALSE(ZA_InOut
.hasPrivateZAInterface());
132 SA ZA_Preserved
= SA(SA::encodeZAState(SA::StateValue::Preserved
));
133 ASSERT_TRUE(ZA_Preserved
.isPreservesZA());
134 ASSERT_FALSE(ZA_Preserved
.isInZA());
135 ASSERT_FALSE(ZA_Preserved
.isOutZA());
136 ASSERT_FALSE(ZA_Preserved
.isInOutZA());
137 ASSERT_FALSE(ZA_Preserved
.isNewZA());
138 ASSERT_TRUE(ZA_Preserved
.sharesZA());
139 ASSERT_TRUE(ZA_Preserved
.hasZAState());
140 ASSERT_TRUE(ZA_Preserved
.hasSharedZAInterface());
141 ASSERT_FALSE(ZA_Preserved
.hasPrivateZAInterface());
143 SA ZA_New
= SA(SA::encodeZAState(SA::StateValue::New
));
144 ASSERT_TRUE(ZA_New
.isNewZA());
145 ASSERT_FALSE(ZA_New
.isInZA());
146 ASSERT_FALSE(ZA_New
.isOutZA());
147 ASSERT_FALSE(ZA_New
.isInOutZA());
148 ASSERT_FALSE(ZA_New
.isPreservesZA());
149 ASSERT_FALSE(ZA_New
.sharesZA());
150 ASSERT_TRUE(ZA_New
.hasZAState());
151 ASSERT_FALSE(ZA_New
.hasSharedZAInterface());
152 ASSERT_TRUE(ZA_New
.hasPrivateZAInterface());
154 ASSERT_FALSE(SA(SA::Normal
).isInZA());
155 ASSERT_FALSE(SA(SA::Normal
).isOutZA());
156 ASSERT_FALSE(SA(SA::Normal
).isInOutZA());
157 ASSERT_FALSE(SA(SA::Normal
).isPreservesZA());
158 ASSERT_FALSE(SA(SA::Normal
).isNewZA());
159 ASSERT_FALSE(SA(SA::Normal
).sharesZA());
160 ASSERT_FALSE(SA(SA::Normal
).hasZAState());
162 // Test ZT0 State interfaces
163 SA ZT0_In
= SA(SA::encodeZT0State(SA::StateValue::In
));
164 ASSERT_TRUE(ZT0_In
.isInZT0());
165 ASSERT_FALSE(ZT0_In
.isOutZT0());
166 ASSERT_FALSE(ZT0_In
.isInOutZT0());
167 ASSERT_FALSE(ZT0_In
.isPreservesZT0());
168 ASSERT_FALSE(ZT0_In
.isNewZT0());
169 ASSERT_TRUE(ZT0_In
.sharesZT0());
170 ASSERT_TRUE(ZT0_In
.hasZT0State());
171 ASSERT_TRUE(ZT0_In
.hasSharedZAInterface());
172 ASSERT_FALSE(ZT0_In
.hasPrivateZAInterface());
174 SA ZT0_Out
= SA(SA::encodeZT0State(SA::StateValue::Out
));
175 ASSERT_TRUE(ZT0_Out
.isOutZT0());
176 ASSERT_FALSE(ZT0_Out
.isInZT0());
177 ASSERT_FALSE(ZT0_Out
.isInOutZT0());
178 ASSERT_FALSE(ZT0_Out
.isPreservesZT0());
179 ASSERT_FALSE(ZT0_Out
.isNewZT0());
180 ASSERT_TRUE(ZT0_Out
.sharesZT0());
181 ASSERT_TRUE(ZT0_Out
.hasZT0State());
182 ASSERT_TRUE(ZT0_Out
.hasSharedZAInterface());
183 ASSERT_FALSE(ZT0_Out
.hasPrivateZAInterface());
185 SA ZT0_InOut
= SA(SA::encodeZT0State(SA::StateValue::InOut
));
186 ASSERT_TRUE(ZT0_InOut
.isInOutZT0());
187 ASSERT_FALSE(ZT0_InOut
.isInZT0());
188 ASSERT_FALSE(ZT0_InOut
.isOutZT0());
189 ASSERT_FALSE(ZT0_InOut
.isPreservesZT0());
190 ASSERT_FALSE(ZT0_InOut
.isNewZT0());
191 ASSERT_TRUE(ZT0_InOut
.sharesZT0());
192 ASSERT_TRUE(ZT0_InOut
.hasZT0State());
193 ASSERT_TRUE(ZT0_InOut
.hasSharedZAInterface());
194 ASSERT_FALSE(ZT0_InOut
.hasPrivateZAInterface());
196 SA ZT0_Preserved
= SA(SA::encodeZT0State(SA::StateValue::Preserved
));
197 ASSERT_TRUE(ZT0_Preserved
.isPreservesZT0());
198 ASSERT_FALSE(ZT0_Preserved
.isInZT0());
199 ASSERT_FALSE(ZT0_Preserved
.isOutZT0());
200 ASSERT_FALSE(ZT0_Preserved
.isInOutZT0());
201 ASSERT_FALSE(ZT0_Preserved
.isNewZT0());
202 ASSERT_TRUE(ZT0_Preserved
.sharesZT0());
203 ASSERT_TRUE(ZT0_Preserved
.hasZT0State());
204 ASSERT_TRUE(ZT0_Preserved
.hasSharedZAInterface());
205 ASSERT_FALSE(ZT0_Preserved
.hasPrivateZAInterface());
207 SA ZT0_New
= SA(SA::encodeZT0State(SA::StateValue::New
));
208 ASSERT_TRUE(ZT0_New
.isNewZT0());
209 ASSERT_FALSE(ZT0_New
.isInZT0());
210 ASSERT_FALSE(ZT0_New
.isOutZT0());
211 ASSERT_FALSE(ZT0_New
.isInOutZT0());
212 ASSERT_FALSE(ZT0_New
.isPreservesZT0());
213 ASSERT_FALSE(ZT0_New
.sharesZT0());
214 ASSERT_TRUE(ZT0_New
.hasZT0State());
215 ASSERT_FALSE(ZT0_New
.hasSharedZAInterface());
216 ASSERT_TRUE(ZT0_New
.hasPrivateZAInterface());
218 ASSERT_FALSE(SA(SA::Normal
).isInZT0());
219 ASSERT_FALSE(SA(SA::Normal
).isOutZT0());
220 ASSERT_FALSE(SA(SA::Normal
).isInOutZT0());
221 ASSERT_FALSE(SA(SA::Normal
).isPreservesZT0());
222 ASSERT_FALSE(SA(SA::Normal
).isNewZT0());
223 ASSERT_FALSE(SA(SA::Normal
).sharesZT0());
224 ASSERT_FALSE(SA(SA::Normal
).hasZT0State());
227 TEST(SMEAttributes
, Transitions
) {
229 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::Normal
)));
230 ASSERT_FALSE(SA(SA::Normal
).requiresPreservingZT0(SA(SA::Normal
)));
231 ASSERT_FALSE(SA(SA::Normal
).requiresDisablingZABeforeCall(SA(SA::Normal
)));
232 ASSERT_FALSE(SA(SA::Normal
).requiresEnablingZAAfterCall(SA(SA::Normal
)));
233 // Normal -> Normal + LocallyStreaming
234 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)));
236 // Normal -> Streaming
237 ASSERT_TRUE(SA(SA::Normal
).requiresSMChange(SA(SA::SM_Enabled
)));
238 // Normal -> Streaming + LocallyStreaming
240 SA(SA::Normal
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)));
242 // Normal -> Streaming-compatible
243 ASSERT_FALSE(SA(SA::Normal
).requiresSMChange(SA(SA::SM_Compatible
)));
244 // Normal -> Streaming-compatible + LocallyStreaming
246 SA(SA::Normal
).requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
248 // Streaming -> Normal
249 ASSERT_TRUE(SA(SA::SM_Enabled
).requiresSMChange(SA(SA::Normal
)));
250 // Streaming -> Normal + LocallyStreaming
252 SA(SA::SM_Enabled
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)));
254 // Streaming -> Streaming
255 ASSERT_FALSE(SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Enabled
)));
256 // Streaming -> Streaming + LocallyStreaming
258 SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)));
260 // Streaming -> Streaming-compatible
261 ASSERT_FALSE(SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Compatible
)));
262 // Streaming -> Streaming-compatible + LocallyStreaming
264 SA(SA::SM_Enabled
).requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
266 // Streaming-compatible -> Normal
267 ASSERT_TRUE(SA(SA::SM_Compatible
).requiresSMChange(SA(SA::Normal
)));
269 SA(SA::SM_Compatible
).requiresSMChange(SA(SA::Normal
| SA::SM_Body
)));
271 // Streaming-compatible -> Streaming
272 ASSERT_TRUE(SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Enabled
)));
273 // Streaming-compatible -> Streaming + LocallyStreaming
275 SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Enabled
| SA::SM_Body
)));
277 // Streaming-compatible -> Streaming-compatible
278 ASSERT_FALSE(SA(SA::SM_Compatible
).requiresSMChange(SA(SA::SM_Compatible
)));
279 // Streaming-compatible -> Streaming-compatible + LocallyStreaming
280 ASSERT_FALSE(SA(SA::SM_Compatible
)
281 .requiresSMChange(SA(SA::SM_Compatible
| SA::SM_Body
)));
283 SA Private_ZA
= SA(SA::Normal
);
284 SA ZA_Shared
= SA(SA::encodeZAState(SA::StateValue::In
));
285 SA ZT0_Shared
= SA(SA::encodeZT0State(SA::StateValue::In
));
286 SA ZA_ZT0_Shared
= SA(SA::encodeZAState(SA::StateValue::In
) |
287 SA::encodeZT0State(SA::StateValue::In
));
289 // Shared ZA -> Private ZA Interface
290 ASSERT_FALSE(ZA_Shared
.requiresDisablingZABeforeCall(Private_ZA
));
291 ASSERT_TRUE(ZA_Shared
.requiresEnablingZAAfterCall(Private_ZA
));
293 // Shared ZT0 -> Private ZA Interface
294 ASSERT_TRUE(ZT0_Shared
.requiresDisablingZABeforeCall(Private_ZA
));
295 ASSERT_TRUE(ZT0_Shared
.requiresPreservingZT0(Private_ZA
));
296 ASSERT_TRUE(ZT0_Shared
.requiresEnablingZAAfterCall(Private_ZA
));
298 // Shared ZA & ZT0 -> Private ZA Interface
299 ASSERT_FALSE(ZA_ZT0_Shared
.requiresDisablingZABeforeCall(Private_ZA
));
300 ASSERT_TRUE(ZA_ZT0_Shared
.requiresPreservingZT0(Private_ZA
));
301 ASSERT_TRUE(ZA_ZT0_Shared
.requiresEnablingZAAfterCall(Private_ZA
));
303 // Shared ZA -> Shared ZA Interface
304 ASSERT_FALSE(ZA_Shared
.requiresDisablingZABeforeCall(ZT0_Shared
));
305 ASSERT_FALSE(ZA_Shared
.requiresEnablingZAAfterCall(ZT0_Shared
));
307 // Shared ZT0 -> Shared ZA Interface
308 ASSERT_FALSE(ZT0_Shared
.requiresDisablingZABeforeCall(ZT0_Shared
));
309 ASSERT_FALSE(ZT0_Shared
.requiresPreservingZT0(ZT0_Shared
));
310 ASSERT_FALSE(ZT0_Shared
.requiresEnablingZAAfterCall(ZT0_Shared
));
312 // Shared ZA & ZT0 -> Shared ZA Interface
313 ASSERT_FALSE(ZA_ZT0_Shared
.requiresDisablingZABeforeCall(ZT0_Shared
));
314 ASSERT_FALSE(ZA_ZT0_Shared
.requiresPreservingZT0(ZT0_Shared
));
315 ASSERT_FALSE(ZA_ZT0_Shared
.requiresEnablingZAAfterCall(ZT0_Shared
));