2 * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 typedef unsigned char uint8_t;
22 typedef unsigned short uint16_t;
23 typedef unsigned int uint32_t;
26 static inline void S4_storerhnew_rr(void *p
, int index
, uint16_t v
)
30 " memh(%1+%2<<#2) = r0.new\n\t"
32 :: "r"(v
), "r"(p
), "r"(index
)
37 static inline void *S4_storerbnew_ap(uint8_t v
)
42 " memb(%0 = ##data) = r0.new\n\t"
50 static inline void *S4_storerhnew_ap(uint16_t v
)
55 " memh(%0 = ##data) = r0.new\n\t"
63 static inline void *S4_storerinew_ap(uint32_t v
)
68 " memw(%0 = ##data) = r0.new\n\t"
76 static inline void S4_storeirbt_io(void *p
, int pred
)
78 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
79 "if (p0) memb(%1+#4)=#27\n\t"
84 static inline void S4_storeirbf_io(void *p
, int pred
)
86 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
87 "if (!p0) memb(%1+#4)=#27\n\t"
92 static inline void S4_storeirbtnew_io(void *p
, int pred
)
95 " p0 = cmp.eq(%0, #1)\n\t"
96 " if (p0.new) memb(%1+#4)=#27\n\t"
102 static inline void S4_storeirbfnew_io(void *p
, int pred
)
105 " p0 = cmp.eq(%0, #1)\n\t"
106 " if (!p0.new) memb(%1+#4)=#27\n\t"
112 static inline void S4_storeirht_io(void *p
, int pred
)
114 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
115 "if (p0) memh(%1+#4)=#27\n\t"
120 static inline void S4_storeirhf_io(void *p
, int pred
)
122 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
123 "if (!p0) memh(%1+#4)=#27\n\t"
128 static inline void S4_storeirhtnew_io(void *p
, int pred
)
131 " p0 = cmp.eq(%0, #1)\n\t"
132 " if (p0.new) memh(%1+#4)=#27\n\t"
138 static inline void S4_storeirhfnew_io(void *p
, int pred
)
141 " p0 = cmp.eq(%0, #1)\n\t"
142 " if (!p0.new) memh(%1+#4)=#27\n\t"
148 static inline void S4_storeirit_io(void *p
, int pred
)
150 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
151 "if (p0) memw(%1+#4)=#27\n\t"
156 static inline void S4_storeirif_io(void *p
, int pred
)
158 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
159 "if (!p0) memw(%1+#4)=#27\n\t"
164 static inline void S4_storeiritnew_io(void *p
, int pred
)
167 " p0 = cmp.eq(%0, #1)\n\t"
168 " if (p0.new) memw(%1+#4)=#27\n\t"
174 static inline void S4_storeirifnew_io(void *p
, int pred
)
177 " p0 = cmp.eq(%0, #1)\n\t"
178 " if (!p0.new) memw(%1+#4)=#27\n\t"
185 * Test that compound-compare-jump is executed in 2 parts
186 * First we have to do all the compares in the packet and
187 * account for auto-anding. Then, we can do the predicated
190 static inline int cmpnd_cmp_jump(void)
196 " p0 = cmp.eq(r5, #7)\n\t"
197 " if (p0.new) jump:nt 1f\n\t"
198 " p0 = cmp.eq(r6, #7)\n\t"
205 : "=r"(retval
) :: "r5", "r6", "p0");
209 static inline int test_clrtnew(int arg1
, int old_val
)
212 asm volatile("r5 = %2\n\t"
214 "p0 = cmp.eq(%1, #1)\n\t"
215 "if (p0.new) r5=#0\n\t"
219 : "r"(arg1
), "r"(old_val
)
226 static void check(int val
, int expect
)
229 printf("ERROR: 0x%04x != 0x%04x\n", val
, expect
);
234 uint32_t init
[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
240 * Write this as a function because we can't guarantee the compiler will
241 * allocate a frame with just the SL2_return_tnew packet.
243 static void SL2_return_tnew(int x
);
244 asm ("SL2_return_tnew:\n\t"
245 " allocframe(#0)\n\t"
247 " memw(##early_exit) = r1\n\t"
249 " p0 = cmp.eq(r0, #1)\n\t"
250 " if (p0.new) dealloc_return:nt\n\t" /* SL2_return_tnew */
253 " memw(##early_exit) = r1\n\t"
254 " dealloc_return\n\t"
257 static long long creg_pair(int x
, int y
)
263 : "=r"(retval
) : "r"(x
), "r"(y
) : "m0", "m1");
270 memcpy(array
, init
, sizeof(array
));
271 S4_storerhnew_rr(array
, 4, 0xffff);
272 check(array
[4], 0xffff);
275 check((uint32_t)S4_storerbnew_ap(0x12), (uint32_t)&data
);
276 check(data
, 0xffffff12);
279 check((uint32_t)S4_storerhnew_ap(0x1234), (uint32_t)&data
);
280 check(data
, 0xffff1234);
283 check((uint32_t)S4_storerinew_ap(0x12345678), (uint32_t)&data
);
284 check(data
, 0x12345678);
287 memcpy(array
, init
, sizeof(array
));
288 S4_storeirbt_io(&array
[1], 1);
290 S4_storeirbt_io(&array
[2], 0);
293 memcpy(array
, init
, sizeof(array
));
294 S4_storeirbf_io(&array
[3], 0);
296 S4_storeirbf_io(&array
[4], 1);
299 memcpy(array
, init
, sizeof(array
));
300 S4_storeirbtnew_io(&array
[5], 1);
302 S4_storeirbtnew_io(&array
[6], 0);
305 memcpy(array
, init
, sizeof(array
));
306 S4_storeirbfnew_io(&array
[7], 0);
308 S4_storeirbfnew_io(&array
[8], 1);
312 memcpy(array
, init
, sizeof(array
));
313 S4_storeirht_io(&array
[1], 1);
315 S4_storeirht_io(&array
[2], 0);
318 memcpy(array
, init
, sizeof(array
));
319 S4_storeirhf_io(&array
[3], 0);
321 S4_storeirhf_io(&array
[4], 1);
324 memcpy(array
, init
, sizeof(array
));
325 S4_storeirhtnew_io(&array
[5], 1);
327 S4_storeirhtnew_io(&array
[6], 0);
330 memcpy(array
, init
, sizeof(array
));
331 S4_storeirhfnew_io(&array
[7], 0);
333 S4_storeirhfnew_io(&array
[8], 1);
337 memcpy(array
, init
, sizeof(array
));
338 S4_storeirit_io(&array
[1], 1);
340 S4_storeirit_io(&array
[2], 0);
343 memcpy(array
, init
, sizeof(array
));
344 S4_storeirif_io(&array
[3], 0);
346 S4_storeirif_io(&array
[4], 1);
349 memcpy(array
, init
, sizeof(array
));
350 S4_storeiritnew_io(&array
[5], 1);
352 S4_storeiritnew_io(&array
[6], 0);
355 memcpy(array
, init
, sizeof(array
));
356 S4_storeirifnew_io(&array
[7], 0);
358 S4_storeirifnew_io(&array
[8], 1);
361 int x
= cmpnd_cmp_jump();
365 check(early_exit
, 0);
367 check(early_exit
, 1);
369 long long pair
= creg_pair(5, 7);
371 check((int)(pair
>> 32), 7);
373 int res
= test_clrtnew(1, 7);
375 res
= test_clrtnew(2, 7);
378 puts(err
? "FAIL" : "PASS");