1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <stdio.h>
19#include <string.h>
20
21typedef unsigned char uint8_t;
22typedef unsigned short uint16_t;
23typedef unsigned int uint32_t;
24
25
26static inline void S4_storerhnew_rr(void *p, int index, uint16_t v)
27{
28 asm volatile("{\n\t"
29 " r0 = %0\n\n"
30 " memh(%1+%2<<#2) = r0.new\n\t"
31 "}\n"
32 :: "r"(v), "r"(p), "r"(index)
33 : "r0", "memory");
34}
35
36static uint32_t data;
37static inline void *S4_storerbnew_ap(uint8_t v)
38{
39 void *ret;
40 asm volatile("{\n\t"
41 " r0 = %1\n\n"
42 " memb(%0 = ##data) = r0.new\n\t"
43 "}\n"
44 : "=r"(ret)
45 : "r"(v)
46 : "r0", "memory");
47 return ret;
48}
49
50static inline void *S4_storerhnew_ap(uint16_t v)
51{
52 void *ret;
53 asm volatile("{\n\t"
54 " r0 = %1\n\n"
55 " memh(%0 = ##data) = r0.new\n\t"
56 "}\n"
57 : "=r"(ret)
58 : "r"(v)
59 : "r0", "memory");
60 return ret;
61}
62
63static inline void *S4_storerinew_ap(uint32_t v)
64{
65 void *ret;
66 asm volatile("{\n\t"
67 " r0 = %1\n\n"
68 " memw(%0 = ##data) = r0.new\n\t"
69 "}\n"
70 : "=r"(ret)
71 : "r"(v)
72 : "r0", "memory");
73 return ret;
74}
75
76static inline void S4_storeirbt_io(void *p, int pred)
77{
78 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
79 "if (p0) memb(%1+#4)=#27\n\t"
80 :: "r"(pred), "r"(p)
81 : "p0", "memory");
82}
83
84static inline void S4_storeirbf_io(void *p, int pred)
85{
86 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
87 "if (!p0) memb(%1+#4)=#27\n\t"
88 :: "r"(pred), "r"(p)
89 : "p0", "memory");
90}
91
92static inline void S4_storeirbtnew_io(void *p, int pred)
93{
94 asm volatile("{\n\t"
95 " p0 = cmp.eq(%0, #1)\n\t"
96 " if (p0.new) memb(%1+#4)=#27\n\t"
97 "}\n\t"
98 :: "r"(pred), "r"(p)
99 : "p0", "memory");
100}
101
102static inline void S4_storeirbfnew_io(void *p, int pred)
103{
104 asm volatile("{\n\t"
105 " p0 = cmp.eq(%0, #1)\n\t"
106 " if (!p0.new) memb(%1+#4)=#27\n\t"
107 "}\n\t"
108 :: "r"(pred), "r"(p)
109 : "p0", "memory");
110}
111
112static inline void S4_storeirht_io(void *p, int pred)
113{
114 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
115 "if (p0) memh(%1+#4)=#27\n\t"
116 :: "r"(pred), "r"(p)
117 : "p0", "memory");
118}
119
120static inline void S4_storeirhf_io(void *p, int pred)
121{
122 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
123 "if (!p0) memh(%1+#4)=#27\n\t"
124 :: "r"(pred), "r"(p)
125 : "p0", "memory");
126}
127
128static inline void S4_storeirhtnew_io(void *p, int pred)
129{
130 asm volatile("{\n\t"
131 " p0 = cmp.eq(%0, #1)\n\t"
132 " if (p0.new) memh(%1+#4)=#27\n\t"
133 "}\n\t"
134 :: "r"(pred), "r"(p)
135 : "p0", "memory");
136}
137
138static inline void S4_storeirhfnew_io(void *p, int pred)
139{
140 asm volatile("{\n\t"
141 " p0 = cmp.eq(%0, #1)\n\t"
142 " if (!p0.new) memh(%1+#4)=#27\n\t"
143 "}\n\t"
144 :: "r"(pred), "r"(p)
145 : "p0", "memory");
146}
147
148static inline void S4_storeirit_io(void *p, int pred)
149{
150 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
151 "if (p0) memw(%1+#4)=#27\n\t"
152 :: "r"(pred), "r"(p)
153 : "p0", "memory");
154}
155
156static inline void S4_storeirif_io(void *p, int pred)
157{
158 asm volatile("p0 = cmp.eq(%0, #1)\n\t"
159 "if (!p0) memw(%1+#4)=#27\n\t"
160 :: "r"(pred), "r"(p)
161 : "p0", "memory");
162}
163
164static inline void S4_storeiritnew_io(void *p, int pred)
165{
166 asm volatile("{\n\t"
167 " p0 = cmp.eq(%0, #1)\n\t"
168 " if (p0.new) memw(%1+#4)=#27\n\t"
169 "}\n\t"
170 :: "r"(pred), "r"(p)
171 : "p0", "memory");
172}
173
174static inline void S4_storeirifnew_io(void *p, int pred)
175{
176 asm volatile("{\n\t"
177 " p0 = cmp.eq(%0, #1)\n\t"
178 " if (!p0.new) memw(%1+#4)=#27\n\t"
179 "}\n\t"
180 :: "r"(pred), "r"(p)
181 : "p0", "memory");
182}
183
184static int L2_ploadrifnew_pi(void *p, int pred)
185{
186 int result;
187 asm volatile("%0 = #31\n\t"
188 "{\n\t"
189 " p0 = cmp.eq(%1, #1)\n\t"
190 " if (!p0.new) %0 = memw(%2++#4)\n\t"
191 "}\n\t"
192 : "=r"(result) : "r"(pred), "r"(p)
193 : "p0");
194 return result;
195}
196
197
198
199
200
201
202
203static inline int cmpnd_cmp_jump(void)
204{
205 int retval;
206 asm ("r5 = #7\n\t"
207 "r6 = #9\n\t"
208 "{\n\t"
209 " p0 = cmp.eq(r5, #7)\n\t"
210 " if (p0.new) jump:nt 1f\n\t"
211 " p0 = cmp.eq(r6, #7)\n\t"
212 "}\n\t"
213 "%0 = #12\n\t"
214 "jump 2f\n\t"
215 "1:\n\t"
216 "%0 = #13\n\t"
217 "2:\n\t"
218 : "=r"(retval) :: "r5", "r6", "p0");
219 return retval;
220}
221
222static inline int test_clrtnew(int arg1, int old_val)
223{
224 int ret;
225 asm volatile("r5 = %2\n\t"
226 "{\n\t"
227 "p0 = cmp.eq(%1, #1)\n\t"
228 "if (p0.new) r5=#0\n\t"
229 "}\n\t"
230 "%0 = r5\n\t"
231 : "=r"(ret)
232 : "r"(arg1), "r"(old_val)
233 : "p0", "r5");
234 return ret;
235}
236
237int err;
238
239static void check(int val, int expect)
240{
241 if (val != expect) {
242 printf("ERROR: 0x%04x != 0x%04x\n", val, expect);
243 err++;
244 }
245}
246
247static void check64(long long val, long long expect)
248{
249 if (val != expect) {
250 printf("ERROR: 0x%016llx != 0x%016llx\n", val, expect);
251 err++;
252 }
253}
254
255uint32_t init[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
256uint32_t array[10];
257
258uint32_t early_exit;
259
260
261
262
263
264static void SL2_return_tnew(int x);
265asm ("SL2_return_tnew:\n\t"
266 " allocframe(#0)\n\t"
267 " r1 = #1\n\t"
268 " memw(##early_exit) = r1\n\t"
269 " {\n\t"
270 " p0 = cmp.eq(r0, #1)\n\t"
271 " if (p0.new) dealloc_return:nt\n\t"
272 " }\n\t"
273 " r1 = #0\n\t"
274 " memw(##early_exit) = r1\n\t"
275 " dealloc_return\n\t"
276 );
277
278static long long creg_pair(int x, int y)
279{
280 long long retval;
281 asm ("m0 = %1\n\t"
282 "m1 = %2\n\t"
283 "%0 = c7:6\n\t"
284 : "=r"(retval) : "r"(x), "r"(y) : "m0", "m1");
285 return retval;
286}
287
288static long long decbin(long long x, long long y, int *pred)
289{
290 long long retval;
291 asm ("%0 = decbin(%2, %3)\n\t"
292 "%1 = p0\n\t"
293 : "=r"(retval), "=r"(*pred)
294 : "r"(x), "r"(y));
295 return retval;
296}
297
298
299static int auto_and(void)
300{
301 int retval;
302 asm ("r5 = #1\n\t"
303 "{\n\t"
304 " p0 = cmp.eq(r1, #1)\n\t"
305 " p0 = cmp.eq(r1, #2)\n\t"
306 "}\n\t"
307 "%0 = p0\n\t"
308 : "=r"(retval)
309 :
310 : "r5", "p0");
311 return retval;
312}
313
314void test_lsbnew(void)
315{
316 int result;
317
318 asm("r0 = #2\n\t"
319 "r1 = #5\n\t"
320 "{\n\t"
321 " p0 = r0\n\t"
322 " if (p0.new) r1 = #3\n\t"
323 "}\n\t"
324 "%0 = r1\n\t"
325 : "=r"(result) :: "r0", "r1", "p0");
326 check(result, 5);
327}
328
329void test_l2fetch(void)
330{
331
332 asm volatile ("l2fetch(r0, r1)\n\t"
333 "l2fetch(r0, r3:2)\n\t");
334}
335
336int main()
337{
338 int res;
339 long long res64;
340 int pred;
341
342 memcpy(array, init, sizeof(array));
343 S4_storerhnew_rr(array, 4, 0xffff);
344 check(array[4], 0xffff);
345
346 data = ~0;
347 check((uint32_t)S4_storerbnew_ap(0x12), (uint32_t)&data);
348 check(data, 0xffffff12);
349
350 data = ~0;
351 check((uint32_t)S4_storerhnew_ap(0x1234), (uint32_t)&data);
352 check(data, 0xffff1234);
353
354 data = ~0;
355 check((uint32_t)S4_storerinew_ap(0x12345678), (uint32_t)&data);
356 check(data, 0x12345678);
357
358
359 memcpy(array, init, sizeof(array));
360 S4_storeirbt_io(&array[1], 1);
361 check(array[2], 27);
362 S4_storeirbt_io(&array[2], 0);
363 check(array[3], 3);
364
365 memcpy(array, init, sizeof(array));
366 S4_storeirbf_io(&array[3], 0);
367 check(array[4], 27);
368 S4_storeirbf_io(&array[4], 1);
369 check(array[5], 5);
370
371 memcpy(array, init, sizeof(array));
372 S4_storeirbtnew_io(&array[5], 1);
373 check(array[6], 27);
374 S4_storeirbtnew_io(&array[6], 0);
375 check(array[7], 7);
376
377 memcpy(array, init, sizeof(array));
378 S4_storeirbfnew_io(&array[7], 0);
379 check(array[8], 27);
380 S4_storeirbfnew_io(&array[8], 1);
381 check(array[9], 9);
382
383
384 memcpy(array, init, sizeof(array));
385 S4_storeirht_io(&array[1], 1);
386 check(array[2], 27);
387 S4_storeirht_io(&array[2], 0);
388 check(array[3], 3);
389
390 memcpy(array, init, sizeof(array));
391 S4_storeirhf_io(&array[3], 0);
392 check(array[4], 27);
393 S4_storeirhf_io(&array[4], 1);
394 check(array[5], 5);
395
396 memcpy(array, init, sizeof(array));
397 S4_storeirhtnew_io(&array[5], 1);
398 check(array[6], 27);
399 S4_storeirhtnew_io(&array[6], 0);
400 check(array[7], 7);
401
402 memcpy(array, init, sizeof(array));
403 S4_storeirhfnew_io(&array[7], 0);
404 check(array[8], 27);
405 S4_storeirhfnew_io(&array[8], 1);
406 check(array[9], 9);
407
408
409 memcpy(array, init, sizeof(array));
410 S4_storeirit_io(&array[1], 1);
411 check(array[2], 27);
412 S4_storeirit_io(&array[2], 0);
413 check(array[3], 3);
414
415 memcpy(array, init, sizeof(array));
416 S4_storeirif_io(&array[3], 0);
417 check(array[4], 27);
418 S4_storeirif_io(&array[4], 1);
419 check(array[5], 5);
420
421 memcpy(array, init, sizeof(array));
422 S4_storeiritnew_io(&array[5], 1);
423 check(array[6], 27);
424 S4_storeiritnew_io(&array[6], 0);
425 check(array[7], 7);
426
427 memcpy(array, init, sizeof(array));
428 S4_storeirifnew_io(&array[7], 0);
429 check(array[8], 27);
430 S4_storeirifnew_io(&array[8], 1);
431 check(array[9], 9);
432
433 memcpy(array, init, sizeof(array));
434 res = L2_ploadrifnew_pi(&array[6], 0);
435 check(res, 6);
436 res = L2_ploadrifnew_pi(&array[7], 1);
437 check(res, 31);
438
439 int x = cmpnd_cmp_jump();
440 check(x, 12);
441
442 SL2_return_tnew(0);
443 check(early_exit, 0);
444 SL2_return_tnew(1);
445 check(early_exit, 1);
446
447 long long pair = creg_pair(5, 7);
448 check((int)pair, 5);
449 check((int)(pair >> 32), 7);
450
451 res = test_clrtnew(1, 7);
452 check(res, 0);
453 res = test_clrtnew(2, 7);
454 check(res, 7);
455
456 res64 = decbin(0xf0f1f2f3f4f5f6f7LL, 0x7f6f5f4f3f2f1f0fLL, &pred);
457 check64(res64, 0x357980003700010cLL);
458 check(pred, 0);
459
460 res64 = decbin(0xfLL, 0x1bLL, &pred);
461 check64(res64, 0x78000100LL);
462 check(pred, 1);
463
464 res = auto_and();
465 check(res, 0);
466
467 test_lsbnew();
468
469 test_l2fetch();
470
471 puts(err ? "FAIL" : "PASS");
472 return err;
473}
474