1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <stdio.h>
34#include <string.h>
35
36int err;
37
38char buf[16] __attribute__((aligned(1 << 16)));
39
40void init_buf(void)
41{
42 int i;
43 for (i = 0; i < 16; i++) {
44 int sign = i % 2 == 0 ? 0x80 : 0;
45 buf[i] = sign | (i + 1);
46 }
47}
48
49void __check(int line, long long result, long long expect)
50{
51 if (result != expect) {
52 printf("ERROR at line %d: 0x%08llx != 0x%08llx\n",
53 line, result, expect);
54 err++;
55 }
56}
57
58#define check(RES, EXP) __check(__LINE__, RES, EXP)
59
60void __checkp(int line, void *p, void *expect)
61{
62 if (p != expect) {
63 printf("ERROR at line %d: 0x%p != 0x%p\n", line, p, expect);
64 err++;
65 }
66}
67
68#define checkp(RES, EXP) __checkp(__LINE__, RES, EXP)
69
70
71
72
73
74#define BxW_LOAD_io(SZ, RES, ADDR, OFF) \
75 __asm__( \
76 "%0 = mem" #SZ "(%1+#" #OFF ")\n\t" \
77 : "=r"(RES) \
78 : "r"(ADDR))
79#define BxW_LOAD_io_Z(RES, ADDR, OFF) \
80 BxW_LOAD_io(ubh, RES, ADDR, OFF)
81#define BxW_LOAD_io_S(RES, ADDR, OFF) \
82 BxW_LOAD_io(bh, RES, ADDR, OFF)
83
84#define TEST_io(NAME, TYPE, SIGN, SIZE, EXT, EXP1, EXP2, EXP3, EXP4) \
85void test_##NAME(void) \
86{ \
87 TYPE result; \
88 init_buf(); \
89 BxW_LOAD_io_##SIGN(result, buf, 0 * (SIZE)); \
90 check(result, (EXP1) | (EXT)); \
91 BxW_LOAD_io_##SIGN(result, buf, 1 * (SIZE)); \
92 check(result, (EXP2) | (EXT)); \
93 BxW_LOAD_io_##SIGN(result, buf, 2 * (SIZE)); \
94 check(result, (EXP3) | (EXT)); \
95 BxW_LOAD_io_##SIGN(result, buf, 3 * (SIZE)); \
96 check(result, (EXP4) | (EXT)); \
97}
98
99
100TEST_io(loadbzw2_io, int, Z, 2, 0x00000000,
101 0x00020081, 0x00040083, 0x00060085, 0x00080087)
102TEST_io(loadbsw2_io, int, S, 2, 0x0000ff00,
103 0x00020081, 0x00040083, 0x00060085, 0x00080087)
104TEST_io(loadbzw4_io, long long, Z, 4, 0x0000000000000000LL,
105 0x0004008300020081LL, 0x0008008700060085LL,
106 0x000c008b000a0089LL, 0x0010008f000e008dLL)
107TEST_io(loadbsw4_io, long long, S, 4, 0x0000ff000000ff00LL,
108 0x0004008300020081LL, 0x0008008700060085LL,
109 0x000c008b000a0089LL, 0x0010008f000e008dLL)
110
111
112
113
114
115#define BxW_LOAD_ur(SZ, RES, SHIFT, IDX) \
116 __asm__( \
117 "%0 = mem" #SZ "(%1<<#" #SHIFT " + ##buf)\n\t" \
118 : "=r"(RES) \
119 : "r"(IDX))
120#define BxW_LOAD_ur_Z(RES, SHIFT, IDX) \
121 BxW_LOAD_ur(ubh, RES, SHIFT, IDX)
122#define BxW_LOAD_ur_S(RES, SHIFT, IDX) \
123 BxW_LOAD_ur(bh, RES, SHIFT, IDX)
124
125#define TEST_ur(NAME, TYPE, SIGN, SHIFT, EXT, RES1, RES2, RES3, RES4) \
126void test_##NAME(void) \
127{ \
128 TYPE result; \
129 init_buf(); \
130 BxW_LOAD_ur_##SIGN(result, (SHIFT), 0); \
131 check(result, (RES1) | (EXT)); \
132 BxW_LOAD_ur_##SIGN(result, (SHIFT), 1); \
133 check(result, (RES2) | (EXT)); \
134 BxW_LOAD_ur_##SIGN(result, (SHIFT), 2); \
135 check(result, (RES3) | (EXT)); \
136 BxW_LOAD_ur_##SIGN(result, (SHIFT), 3); \
137 check(result, (RES4) | (EXT)); \
138} \
139
140TEST_ur(loadbzw2_ur, int, Z, 1, 0x00000000,
141 0x00020081, 0x00040083, 0x00060085, 0x00080087)
142TEST_ur(loadbsw2_ur, int, S, 1, 0x0000ff00,
143 0x00020081, 0x00040083, 0x00060085, 0x00080087)
144TEST_ur(loadbzw4_ur, long long, Z, 2, 0x0000000000000000LL,
145 0x0004008300020081LL, 0x0008008700060085LL,
146 0x000c008b000a0089LL, 0x0010008f000e008dLL)
147TEST_ur(loadbsw4_ur, long long, S, 2, 0x0000ff000000ff00LL,
148 0x0004008300020081LL, 0x0008008700060085LL,
149 0x000c008b000a0089LL, 0x0010008f000e008dLL)
150
151
152
153
154
155#define BxW_LOAD_ap(SZ, RES, PTR, ADDR) \
156 __asm__( \
157 "%0 = mem" #SZ "(%1 = ##" #ADDR ")\n\t" \
158 : "=r"(RES), "=r"(PTR))
159#define BxW_LOAD_ap_Z(RES, PTR, ADDR) \
160 BxW_LOAD_ap(ubh, RES, PTR, ADDR)
161#define BxW_LOAD_ap_S(RES, PTR, ADDR) \
162 BxW_LOAD_ap(bh, RES, PTR, ADDR)
163
164#define TEST_ap(NAME, TYPE, SIGN, SIZE, EXT, RES1, RES2, RES3, RES4) \
165void test_##NAME(void) \
166{ \
167 TYPE result; \
168 void *ptr; \
169 init_buf(); \
170 BxW_LOAD_ap_##SIGN(result, ptr, (buf + 0 * (SIZE))); \
171 check(result, (RES1) | (EXT)); \
172 checkp(ptr, &buf[0 * (SIZE)]); \
173 BxW_LOAD_ap_##SIGN(result, ptr, (buf + 1 * (SIZE))); \
174 check(result, (RES2) | (EXT)); \
175 checkp(ptr, &buf[1 * (SIZE)]); \
176 BxW_LOAD_ap_##SIGN(result, ptr, (buf + 2 * (SIZE))); \
177 check(result, (RES3) | (EXT)); \
178 checkp(ptr, &buf[2 * (SIZE)]); \
179 BxW_LOAD_ap_##SIGN(result, ptr, (buf + 3 * (SIZE))); \
180 check(result, (RES4) | (EXT)); \
181 checkp(ptr, &buf[3 * (SIZE)]); \
182}
183
184TEST_ap(loadbzw2_ap, int, Z, 2, 0x00000000,
185 0x00020081, 0x00040083, 0x00060085, 0x00080087)
186TEST_ap(loadbsw2_ap, int, S, 2, 0x0000ff00,
187 0x00020081, 0x00040083, 0x00060085, 0x00080087)
188TEST_ap(loadbzw4_ap, long long, Z, 4, 0x0000000000000000LL,
189 0x0004008300020081LL, 0x0008008700060085LL,
190 0x000c008b000a0089LL, 0x0010008f000e008dLL)
191TEST_ap(loadbsw4_ap, long long, S, 4, 0x0000ff000000ff00LL,
192 0x0004008300020081LL, 0x0008008700060085LL,
193 0x000c008b000a0089LL, 0x0010008f000e008dLL)
194
195
196
197
198
199#define BxW_LOAD_pr(SZ, RES, PTR, INC) \
200 __asm__( \
201 "m0 = %2\n\t" \
202 "%0 = mem" #SZ "(%1++m0)\n\t" \
203 : "=r"(RES), "+r"(PTR) \
204 : "r"(INC) \
205 : "m0")
206#define BxW_LOAD_pr_Z(RES, PTR, INC) \
207 BxW_LOAD_pr(ubh, RES, PTR, INC)
208#define BxW_LOAD_pr_S(RES, PTR, INC) \
209 BxW_LOAD_pr(bh, RES, PTR, INC)
210
211#define TEST_pr(NAME, TYPE, SIGN, SIZE, EXT, RES1, RES2, RES3, RES4) \
212void test_##NAME(void) \
213{ \
214 TYPE result; \
215 void *ptr = buf; \
216 init_buf(); \
217 BxW_LOAD_pr_##SIGN(result, ptr, (SIZE)); \
218 check(result, (RES1) | (EXT)); \
219 checkp(ptr, &buf[1 * (SIZE)]); \
220 BxW_LOAD_pr_##SIGN(result, ptr, (SIZE)); \
221 check(result, (RES2) | (EXT)); \
222 checkp(ptr, &buf[2 * (SIZE)]); \
223 BxW_LOAD_pr_##SIGN(result, ptr, (SIZE)); \
224 check(result, (RES3) | (EXT)); \
225 checkp(ptr, &buf[3 * (SIZE)]); \
226 BxW_LOAD_pr_##SIGN(result, ptr, (SIZE)); \
227 check(result, (RES4) | (EXT)); \
228 checkp(ptr, &buf[4 * (SIZE)]); \
229}
230
231TEST_pr(loadbzw2_pr, int, Z, 2, 0x00000000,
232 0x00020081, 0x0040083, 0x00060085, 0x00080087)
233TEST_pr(loadbsw2_pr, int, S, 2, 0x0000ff00,
234 0x00020081, 0x0040083, 0x00060085, 0x00080087)
235TEST_pr(loadbzw4_pr, long long, Z, 4, 0x0000000000000000LL,
236 0x0004008300020081LL, 0x0008008700060085LL,
237 0x000c008b000a0089LL, 0x0010008f000e008dLL)
238TEST_pr(loadbsw4_pr, long long, S, 4, 0x0000ff000000ff00LL,
239 0x0004008300020081LL, 0x0008008700060085LL,
240 0x000c008b000a0089LL, 0x0010008f000e008dLL)
241
242
243
244
245
246#define BxW_LOAD_pbr(SZ, RES, PTR) \
247 __asm__( \
248 "r4 = #(1 << (16 - 3))\n\t" \
249 "m0 = r4\n\t" \
250 "%0 = mem" #SZ "(%1++m0:brev)\n\t" \
251 : "=r"(RES), "+r"(PTR) \
252 : \
253 : "r4", "m0")
254#define BxW_LOAD_pbr_Z(RES, PTR) \
255 BxW_LOAD_pbr(ubh, RES, PTR)
256#define BxW_LOAD_pbr_S(RES, PTR) \
257 BxW_LOAD_pbr(bh, RES, PTR)
258
259#define TEST_pbr(NAME, TYPE, SIGN, EXT, RES1, RES2, RES3, RES4) \
260void test_##NAME(void) \
261{ \
262 TYPE result; \
263 void *ptr = buf; \
264 init_buf(); \
265 BxW_LOAD_pbr_##SIGN(result, ptr); \
266 check(result, (RES1) | (EXT)); \
267 BxW_LOAD_pbr_##SIGN(result, ptr); \
268 check(result, (RES2) | (EXT)); \
269 BxW_LOAD_pbr_##SIGN(result, ptr); \
270 check(result, (RES3) | (EXT)); \
271 BxW_LOAD_pbr_##SIGN(result, ptr); \
272 check(result, (RES4) | (EXT)); \
273}
274
275TEST_pbr(loadbzw2_pbr, int, Z, 0x00000000,
276 0x00020081, 0x00060085, 0x00040083, 0x00080087)
277TEST_pbr(loadbsw2_pbr, int, S, 0x0000ff00,
278 0x00020081, 0x00060085, 0x00040083, 0x00080087)
279TEST_pbr(loadbzw4_pbr, long long, Z, 0x0000000000000000LL,
280 0x0004008300020081LL, 0x0008008700060085LL,
281 0x0006008500040083LL, 0x000a008900080087LL)
282TEST_pbr(loadbsw4_pbr, long long, S, 0x0000ff000000ff00LL,
283 0x0004008300020081LL, 0x0008008700060085LL,
284 0x0006008500040083LL, 0x000a008900080087LL)
285
286
287
288
289
290#define BxW_LOAD_pi(SZ, RES, PTR, INC) \
291 __asm__( \
292 "%0 = mem" #SZ "(%1++#" #INC ")\n\t" \
293 : "=r"(RES), "+r"(PTR))
294#define BxW_LOAD_pi_Z(RES, PTR, INC) \
295 BxW_LOAD_pi(ubh, RES, PTR, INC)
296#define BxW_LOAD_pi_S(RES, PTR, INC) \
297 BxW_LOAD_pi(bh, RES, PTR, INC)
298
299#define TEST_pi(NAME, TYPE, SIGN, INC, EXT, RES1, RES2, RES3, RES4) \
300void test_##NAME(void) \
301{ \
302 TYPE result; \
303 void *ptr = buf; \
304 init_buf(); \
305 BxW_LOAD_pi_##SIGN(result, ptr, (INC)); \
306 check(result, (RES1) | (EXT)); \
307 checkp(ptr, &buf[1 * (INC)]); \
308 BxW_LOAD_pi_##SIGN(result, ptr, (INC)); \
309 check(result, (RES2) | (EXT)); \
310 checkp(ptr, &buf[2 * (INC)]); \
311 BxW_LOAD_pi_##SIGN(result, ptr, (INC)); \
312 check(result, (RES3) | (EXT)); \
313 checkp(ptr, &buf[3 * (INC)]); \
314 BxW_LOAD_pi_##SIGN(result, ptr, (INC)); \
315 check(result, (RES4) | (EXT)); \
316 checkp(ptr, &buf[4 * (INC)]); \
317}
318
319TEST_pi(loadbzw2_pi, int, Z, 2, 0x00000000,
320 0x00020081, 0x00040083, 0x00060085, 0x00080087)
321TEST_pi(loadbsw2_pi, int, S, 2, 0x0000ff00,
322 0x00020081, 0x00040083, 0x00060085, 0x00080087)
323TEST_pi(loadbzw4_pi, long long, Z, 4, 0x0000000000000000LL,
324 0x0004008300020081LL, 0x0008008700060085LL,
325 0x000c008b000a0089LL, 0x0010008f000e008dLL)
326TEST_pi(loadbsw4_pi, long long, S, 4, 0x0000ff000000ff00LL,
327 0x0004008300020081LL, 0x0008008700060085LL,
328 0x000c008b000a0089LL, 0x0010008f000e008dLL)
329
330
331
332
333
334#define BxW_LOAD_pci(SZ, RES, PTR, START, LEN, INC) \
335 __asm__( \
336 "r4 = %3\n\t" \
337 "m0 = r4\n\t" \
338 "cs0 = %2\n\t" \
339 "%0 = mem" #SZ "(%1++#" #INC ":circ(m0))\n\t" \
340 : "=r"(RES), "+r"(PTR) \
341 : "r"(START), "r"(LEN) \
342 : "r4", "m0", "cs0")
343#define BxW_LOAD_pci_Z(RES, PTR, START, LEN, INC) \
344 BxW_LOAD_pci(ubh, RES, PTR, START, LEN, INC)
345#define BxW_LOAD_pci_S(RES, PTR, START, LEN, INC) \
346 BxW_LOAD_pci(bh, RES, PTR, START, LEN, INC)
347
348#define TEST_pci(NAME, TYPE, SIGN, LEN, INC, EXT, RES1, RES2, RES3, RES4) \
349void test_##NAME(void) \
350{ \
351 TYPE result; \
352 void *ptr = buf; \
353 init_buf(); \
354 BxW_LOAD_pci_##SIGN(result, ptr, buf, (LEN), (INC)); \
355 check(result, (RES1) | (EXT)); \
356 checkp(ptr, &buf[(1 * (INC)) % (LEN)]); \
357 BxW_LOAD_pci_##SIGN(result, ptr, buf, (LEN), (INC)); \
358 check(result, (RES2) | (EXT)); \
359 checkp(ptr, &buf[(2 * (INC)) % (LEN)]); \
360 BxW_LOAD_pci_##SIGN(result, ptr, buf, (LEN), (INC)); \
361 check(result, (RES3) | (EXT)); \
362 checkp(ptr, &buf[(3 * (INC)) % (LEN)]); \
363 BxW_LOAD_pci_##SIGN(result, ptr, buf, (LEN), (INC)); \
364 check(result, (RES4) | (EXT)); \
365 checkp(ptr, &buf[(4 * (INC)) % (LEN)]); \
366}
367
368TEST_pci(loadbzw2_pci, int, Z, 6, 2, 0x00000000,
369 0x00020081, 0x00040083, 0x00060085, 0x00020081)
370TEST_pci(loadbsw2_pci, int, S, 6, 2, 0x0000ff00,
371 0x00020081, 0x00040083, 0x00060085, 0x00020081)
372TEST_pci(loadbzw4_pci, long long, Z, 8, 4, 0x0000000000000000LL,
373 0x0004008300020081LL, 0x0008008700060085LL,
374 0x0004008300020081LL, 0x0008008700060085LL)
375TEST_pci(loadbsw4_pci, long long, S, 8, 4, 0x0000ff000000ff00LL,
376 0x0004008300020081LL, 0x0008008700060085LL,
377 0x0004008300020081LL, 0x0008008700060085LL)
378
379
380
381
382
383#define BxW_LOAD_pcr(SZ, RES, PTR, START, LEN, INC) \
384 __asm__( \
385 "r4 = %2\n\t" \
386 "m1 = r4\n\t" \
387 "cs1 = %3\n\t" \
388 "%0 = mem" #SZ "(%1++I:circ(m1))\n\t" \
389 : "=r"(RES), "+r"(PTR) \
390 : "r"((((INC) & 0x7f) << 17) | ((LEN) & 0x1ffff)), \
391 "r"(START) \
392 : "r4", "m1", "cs1")
393#define BxW_LOAD_pcr_Z(RES, PTR, START, LEN, INC) \
394 BxW_LOAD_pcr(ubh, RES, PTR, START, LEN, INC)
395#define BxW_LOAD_pcr_S(RES, PTR, START, LEN, INC) \
396 BxW_LOAD_pcr(bh, RES, PTR, START, LEN, INC)
397
398#define TEST_pcr(NAME, TYPE, SIGN, SIZE, LEN, INC, \
399 EXT, RES1, RES2, RES3, RES4) \
400void test_##NAME(void) \
401{ \
402 TYPE result; \
403 void *ptr = buf; \
404 init_buf(); \
405 BxW_LOAD_pcr_##SIGN(result, ptr, buf, (LEN), (INC)); \
406 check(result, (RES1) | (EXT)); \
407 checkp(ptr, &buf[(1 * (INC) * (SIZE)) % (LEN)]); \
408 BxW_LOAD_pcr_##SIGN(result, ptr, buf, (LEN), (INC)); \
409 check(result, (RES2) | (EXT)); \
410 checkp(ptr, &buf[(2 * (INC) * (SIZE)) % (LEN)]); \
411 BxW_LOAD_pcr_##SIGN(result, ptr, buf, (LEN), (INC)); \
412 check(result, (RES3) | (EXT)); \
413 checkp(ptr, &buf[(3 * (INC) * (SIZE)) % (LEN)]); \
414 BxW_LOAD_pcr_##SIGN(result, ptr, buf, (LEN), (INC)); \
415 check(result, (RES4) | (EXT)); \
416 checkp(ptr, &buf[(4 * (INC) * (SIZE)) % (LEN)]); \
417}
418
419TEST_pcr(loadbzw2_pcr, int, Z, 2, 8, 2, 0x00000000,
420 0x00020081, 0x00060085, 0x00020081, 0x00060085)
421TEST_pcr(loadbsw2_pcr, int, S, 2, 8, 2, 0x0000ff00,
422 0x00020081, 0x00060085, 0x00020081, 0x00060085)
423TEST_pcr(loadbzw4_pcr, long long, Z, 4, 8, 1, 0x0000000000000000LL,
424 0x0004008300020081LL, 0x0008008700060085LL,
425 0x0004008300020081LL, 0x0008008700060085LL)
426TEST_pcr(loadbsw4_pcr, long long, S, 4, 8, 1, 0x0000ff000000ff00LL,
427 0x0004008300020081LL, 0x0008008700060085LL,
428 0x0004008300020081LL, 0x0008008700060085LL)
429
430int main()
431{
432 test_loadbzw2_io();
433 test_loadbsw2_io();
434 test_loadbzw4_io();
435 test_loadbsw4_io();
436
437 test_loadbzw2_ur();
438 test_loadbsw2_ur();
439 test_loadbzw4_ur();
440 test_loadbsw4_ur();
441
442 test_loadbzw2_ap();
443 test_loadbsw2_ap();
444 test_loadbzw4_ap();
445 test_loadbsw4_ap();
446
447 test_loadbzw2_pr();
448 test_loadbsw2_pr();
449 test_loadbzw4_pr();
450 test_loadbsw4_pr();
451
452 test_loadbzw2_pbr();
453 test_loadbsw2_pbr();
454 test_loadbzw4_pbr();
455 test_loadbsw4_pbr();
456
457 test_loadbzw2_pi();
458 test_loadbsw2_pi();
459 test_loadbzw4_pi();
460 test_loadbsw4_pi();
461
462 test_loadbzw2_pci();
463 test_loadbsw2_pci();
464 test_loadbzw4_pci();
465 test_loadbsw4_pci();
466
467 test_loadbzw2_pcr();
468 test_loadbsw2_pcr();
469 test_loadbzw4_pcr();
470 test_loadbsw4_pcr();
471
472 puts(err ? "FAIL" : "PASS");
473 return err ? 1 : 0;
474}
475