7 /* Program that checks all numbers of args (0 through 12) work for
8 wrapping. Also calls originals which trash all the iregs in an
9 attempt to shake out any problems caused by insufficient saving of
10 caller-save registers around the hidden call instruction. */
12 typedef unsigned int UInt
;
14 #define ROL(_x,n) (((_x) << n) | ((UInt)(_x)) >> ((8*sizeof(UInt)-n)))
16 #define TRASH_IREGS(_rlval, _vec) \
18 register UInt* vec = (_vec); \
19 /* x86 spills for v > 4, amd64 for v > 12. Getting ppc */ \
20 /* to spill is quite difficult, requiring v > 28 or so. */ \
21 register UInt i, sum = 0; \
22 register UInt v1 = vec[1-1]; \
23 register UInt v2 = vec[2-1]; \
24 register UInt v3 = vec[3-1]; \
25 register UInt v4 = vec[4-1]; \
26 register UInt v5 = vec[5-1]; \
27 register UInt v6 = vec[6-1]; \
28 register UInt v7 = vec[7-1]; \
29 register UInt v8 = vec[8-1]; \
30 register UInt v9 = vec[9-1]; \
31 register UInt v10 = vec[10-1]; \
32 register UInt v11 = vec[11-1]; \
33 register UInt v12 = vec[12-1]; \
34 register UInt v13 = vec[13-1]; \
35 register UInt v14 = vec[14-1]; \
36 register UInt v15 = vec[15-1]; \
37 register UInt v16 = vec[16-1]; \
38 register UInt v17 = vec[17-1]; \
39 register UInt v18 = vec[18-1]; \
40 register UInt v19 = vec[19-1]; \
41 register UInt v20 = vec[20-1]; \
42 register UInt v21 = vec[21-1]; \
43 register UInt v22 = vec[22-1]; \
44 register UInt v23 = vec[23-1]; \
45 register UInt v24 = vec[24-1]; \
46 register UInt v25 = vec[25-1]; \
47 register UInt v26 = vec[26-1]; \
48 register UInt v27 = vec[27-1]; \
49 register UInt v28 = vec[28-1]; \
50 register UInt v29 = vec[29-1]; \
51 for (i = 0; i < 50; i++) { \
81 sum ^= ((0xFFF & v1) * i); \
114 #if defined(__clang__)
115 #define ATTRIBUTE_OPTNONE __attribute__((optnone))
117 #define ATTRIBUTE_OPTNONE
122 /* Returns one, in a way that gcc probably can't constant fold out */
124 volatile int one_actual_return_value
= 0; /* the value one() returns */
126 __attribute__((noinline
))
130 for (i
= 0; i
< 7; i
++)
132 a
[3] = 3+one_actual_return_value
;
134 for (i
= 7-1; i
>= 0; i
--)
139 #define LOOPS_START \
140 { register int len = one(); \
141 register int x0; for (x0 = 0x1000; x0 < 0x1000+len; x0++) { \
142 register int x1; for (x1 = 0x1100; x1 < 0x1100+len; x1++) { \
143 register int x2; for (x2 = 0x1200; x2 < 0x1200+len; x2++) { \
144 register int x3; for (x3 = 0x1300; x3 < 0x1300+len; x3++) { \
145 register int x4; for (x4 = 0x1400; x4 < 0x1400+len; x4++) { \
146 register int x5; for (x5 = 0x1500; x5 < 0x1500+len; x5++) { \
147 register int x6; for (x6 = 0x1600; x6 < 0x1600+len; x6++) { \
148 register int x7; for (x7 = 0x1700; x7 < 0x1700+len; x7++) { \
149 register int x8; for (x8 = 0x1800; x8 < 0x1800+len; x8++) { \
150 register int x9; for (x9 = 0x1900; x9 < 0x1900+len; x9++) { \
151 register int xA; for (xA = 0x1A00; xA < 0x1A00+len; xA++) { \
152 register int xB; for (xB = 0x1B00; xB < 0x1B00+len; xB++) { \
153 register int xC; for (xC = 0x1C00; xC < 0x1C00+len; xC++) { \
154 register int xD; for (xD = 0x1D00; xD < 0x1D00+len; xD++) { \
155 register int xE; for (xE = 0x1E00; xE < 0x1E00+len; xE++) { \
156 register int xF; for (xF = 0x1F00; xF < 0x1F00+len; xF++) { \
160 assert(xF >= 0x1F00 && xF <= 0x1F00+len); } \
161 assert(xE >= 0x1E00 && xE <= 0x1E00+len); } \
162 assert(xD >= 0x1D00 && xD <= 0x1D00+len); } \
163 assert(xC >= 0x1C00 && xC <= 0x1C00+len); } \
164 assert(xB >= 0x1B00 && xB <= 0x1B00+len); } \
165 assert(xA >= 0x1A00 && xA <= 0x1A00+len); } \
166 assert(x9 >= 0x1900 && x9 <= 0x1900+len); } \
167 assert(x8 >= 0x1800 && x8 <= 0x1800+len); } \
168 assert(x7 >= 0x1700 && x7 <= 0x1700+len); } \
169 assert(x6 >= 0x1600 && x6 <= 0x1600+len); } \
170 assert(x5 >= 0x1500 && x5 <= 0x1500+len); } \
171 assert(x4 >= 0x1400 && x4 <= 0x1400+len); } \
172 assert(x3 >= 0x1300 && x3 <= 0x1300+len); } \
173 assert(x2 >= 0x1200 && x2 <= 0x1200+len); } \
174 assert(x1 >= 0x1100 && x1 <= 0x1100+len); } \
175 assert(x0 >= 0x1000 && x0 <= 0x1000+len); } \
178 /* General idea is for the wrappers to use LOOPS_START / LOOPS_END to
179 soak up lots of int registers. And the orig fn uses TRASH_IREGS to
180 do the same. If there is insufficient saving of caller-saves regs
181 by the CALL_FN_* macros, then hopefully the assertions in LOOPS_END
184 /* --------------- 0 --------------- */
190 UInt
* words
= calloc(200, sizeof(UInt
));
191 TRASH_IREGS(r
, words
);
196 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_0
) ( UInt a1
)
200 VALGRIND_GET_ORIG_FN(fn
);
202 printf("fn_0 wrapper pre ()\n");
204 printf("fn_0 wrapper post1 = %d\n", (int)r
);
206 printf("fn_0 wrapper post2 = %d\n", (int)r
);
211 /* --------------- 1 --------------- */
214 UInt
fn_1 ( UInt a1
)
217 UInt
* words
= calloc(200, sizeof(UInt
));
219 TRASH_IREGS(r
, words
);
224 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_1
) ( UInt a1
)
228 VALGRIND_GET_ORIG_FN(fn
);
230 printf("fn_1 wrapper pre ( %d )\n", (int)a1
);
231 CALL_FN_W_W(r
, fn
, a1
);
232 printf("fn_1 wrapper post1 = %d\n", (int)r
);
234 printf("fn_1 wrapper post2 = %d\n", (int)r
);
239 /* --------------- 2 --------------- */
242 UInt
fn_2 ( UInt a1
, UInt a2
)
245 UInt
* words
= calloc(200, sizeof(UInt
));
248 TRASH_IREGS(r
, words
);
253 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_2
) ( UInt a1
, UInt a2
)
257 VALGRIND_GET_ORIG_FN(fn
);
259 printf("fn_2 wrapper pre ( %d, %d )\n", (int)a1
, (int)a2
);
260 CALL_FN_W_WW(r
, fn
, a1
, a2
);
261 printf("fn_2 wrapper post1 = %d\n", (int)r
);
262 CALL_FN_v_WW(fn
, a1
, a2
);
263 printf("fn_2 wrapper post2 = %d\n", (int)r
);
268 /* --------------- 3 --------------- */
271 UInt
fn_3 ( UInt a1
, UInt a2
, UInt a3
)
274 UInt
* words
= calloc(200, sizeof(UInt
));
278 TRASH_IREGS(r
, words
);
283 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_3
) ( UInt a1
, UInt a2
, UInt a3
)
287 VALGRIND_GET_ORIG_FN(fn
);
289 printf("fn_3 wrapper pre ( %d, %d, %d )\n", (int)a1
, (int)a2
, (int)a3
);
290 CALL_FN_W_WWW(r
, fn
, a1
, a2
, a3
);
291 printf("fn_3 wrapper post1 = %d\n", (int)r
);
292 CALL_FN_v_WWW(fn
, a1
, a2
, a3
);
293 printf("fn_3 wrapper post2 = %d\n", (int)r
);
298 /* --------------- 4 --------------- */
301 UInt
fn_4 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
)
304 UInt
* words
= calloc(200, sizeof(UInt
));
309 TRASH_IREGS(r
, words
);
314 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_4
)
315 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
)
319 VALGRIND_GET_ORIG_FN(fn
);
321 printf("fn_4 wrapper pre ( %d, %d, %d, %d )\n",
322 (int)a1
, (int)a2
, (int)a3
, (int)a4
);
323 CALL_FN_W_WWWW(r
, fn
, a1
, a2
, a3
, a4
);
324 printf("fn_4 wrapper post1 = %d\n", (int)r
);
329 /* --------------- 5 --------------- */
332 UInt
fn_5 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
)
335 UInt
* words
= calloc(200, sizeof(UInt
));
341 TRASH_IREGS(r
, words
);
346 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_5
)
347 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
)
351 VALGRIND_GET_ORIG_FN(fn
);
353 printf("fn_5 wrapper pre ( %d, %d, %d, %d, %d )\n",
354 (int)a1
, (int)a2
, (int)a3
, (int)a4
, (int)a5
);
355 CALL_FN_W_5W(r
, fn
, a1
, a2
, a3
, a4
, a5
);
356 printf("fn_5 wrapper post1 = %d\n", (int)r
);
361 /* --------------- 6 --------------- */
364 UInt
fn_6 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
)
367 UInt
* words
= calloc(200, sizeof(UInt
));
374 TRASH_IREGS(r
, words
);
379 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_6
)
380 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
)
384 VALGRIND_GET_ORIG_FN(fn
);
386 printf("fn_6 wrapper pre ( %d, %d, %d, %d, %d, %d )\n",
387 (int)a1
, (int)a2
, (int)a3
, (int)a4
, (int)a5
, (int)a6
);
388 CALL_FN_W_6W(r
, fn
, a1
, a2
, a3
, a4
, a5
, a6
);
389 printf("fn_6 wrapper post1 = %d\n", (int)r
);
394 /* --------------- 7 --------------- */
397 UInt
fn_7 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
401 UInt
* words
= calloc(200, sizeof(UInt
));
409 TRASH_IREGS(r
, words
);
414 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_7
)
415 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
420 VALGRIND_GET_ORIG_FN(fn
);
422 printf("fn_7 wrapper pre ( %d, %d, %d, %d, %d, %d, %d )\n",
423 (int)a1
, (int)a2
, (int)a3
, (int)a4
, (int)a5
, (int)a6
,
425 CALL_FN_W_7W(r
, fn
, a1
, a2
, a3
, a4
, a5
, a6
, a7
);
426 printf("fn_7 wrapper post1 = %d\n", (int)r
);
431 /* --------------- 8 --------------- */
434 UInt
fn_8 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
438 UInt
* words
= calloc(200, sizeof(UInt
));
447 TRASH_IREGS(r
, words
);
452 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_8
)
453 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
458 VALGRIND_GET_ORIG_FN(fn
);
460 printf("fn_8 wrapper pre ( %d, %d, %d, %d, %d, %d, %d, %d )\n",
461 (int)a1
, (int)a2
, (int)a3
, (int)a4
, (int)a5
, (int)a6
,
463 CALL_FN_W_8W(r
, fn
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
);
464 printf("fn_8 wrapper post1 = %d\n", (int)r
);
469 /* --------------- 9 --------------- */
472 UInt
fn_9 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
473 UInt a7
, UInt a8
, UInt a9
)
476 UInt
* words
= calloc(200, sizeof(UInt
));
486 TRASH_IREGS(r
, words
);
491 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_9
)
492 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
493 UInt a7
, UInt a8
, UInt a9
)
497 VALGRIND_GET_ORIG_FN(fn
);
499 printf("fn_9 wrapper pre ( %d, %d, %d, %d, %d, %d, %d, %d, %d )\n",
500 (int)a1
, (int)a2
, (int)a3
, (int)a4
, (int)a5
, (int)a6
,
501 (int)a7
, (int)a8
, (int)a9
);
502 CALL_FN_W_9W(r
, fn
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
503 printf("fn_9 wrapper post1 = %d\n", (int)r
);
508 /* --------------- 10 --------------- */
511 UInt
fn_10 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
512 UInt a7
, UInt a8
, UInt a9
, UInt a10
)
515 UInt
* words
= calloc(200, sizeof(UInt
));
526 TRASH_IREGS(r
, words
);
531 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_10
)
532 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
533 UInt a7
, UInt a8
, UInt a9
, UInt a10
)
537 VALGRIND_GET_ORIG_FN(fn
);
539 printf("fn_10 wrapper pre ( %d, %d, %d, %d, %d, %d, %d, %d, %d, %d )\n",
540 (int)a1
, (int)a2
, (int)a3
, (int)a4
, (int)a5
, (int)a6
,
541 (int)a7
, (int)a8
, (int)a9
, (int)a10
);
542 CALL_FN_W_10W(r
, fn
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
);
543 printf("fn_10 wrapper post1 = %d\n", (int)r
);
548 /* --------------- 11 --------------- */
551 UInt
fn_11 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
552 UInt a7
, UInt a8
, UInt a9
, UInt a10
, UInt a11
)
555 UInt
* words
= calloc(200, sizeof(UInt
));
567 TRASH_IREGS(r
, words
);
572 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_11
)
573 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
574 UInt a7
, UInt a8
, UInt a9
, UInt a10
, UInt a11
)
578 VALGRIND_GET_ORIG_FN(fn
);
580 printf("fn_11 wrapper pre ( %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d )\n",
581 (int)a1
, (int)a2
, (int)a3
, (int)a4
, (int)a5
, (int)a6
,
582 (int)a7
, (int)a8
, (int)a9
, (int)a10
, (int)a11
);
583 CALL_FN_W_11W(r
, fn
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
, a11
);
584 printf("fn_11 wrapper post1 = %d\n", (int)r
);
589 /* --------------- 12 --------------- */
591 __attribute__((noinline
))
592 UInt
fn_12 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
593 UInt a7
, UInt a8
, UInt a9
, UInt a10
, UInt a11
, UInt a12
)
596 UInt
* words
= calloc(200, sizeof(UInt
));
609 TRASH_IREGS(r
, words
);
614 UInt
I_WRAP_SONAME_FNNAME_ZU(NONE
,fn_12
)
615 ( UInt a1
, UInt a2
, UInt a3
, UInt a4
, UInt a5
, UInt a6
,
616 UInt a7
, UInt a8
, UInt a9
, UInt a10
, UInt a11
, UInt a12
)
620 VALGRIND_GET_ORIG_FN(fn
);
622 printf("fn_12 wrapper pre ( %d, %d, %d, %d, %d, %d, "
623 "%d, %d, %d, %d, %d, %d )\n",
624 (int)a1
, (int)a2
, (int)a3
, (int)a4
, (int)a5
, (int)a6
,
625 (int)a7
, (int)a8
, (int)a9
, (int)a10
, (int)a11
, (int)a12
);
626 CALL_FN_W_12W(r
, fn
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
, a11
, a12
);
627 printf("fn_12 wrapper post1 = %d\n", (int)r
);
632 /* --------------- main --------------- */
638 one_actual_return_value
= 1;
640 printf("fn_0 ...\n");
642 printf(" ... %d\n\n", (int)w
);
644 printf("fn_1 ...\n");
646 printf(" ... %d\n\n", (int)w
);
648 printf("fn_2 ...\n");
650 printf(" ... %d\n\n", (int)w
);
652 printf("fn_3 ...\n");
654 printf(" ... %d\n\n", (int)w
);
656 printf("fn_4 ...\n");
657 w
= fn_4(42,43,44,45);
658 printf(" ... %d\n\n", (int)w
);
660 printf("fn_5 ...\n");
661 w
= fn_5(42,43,44,45,46);
662 printf(" ... %d\n\n", (int)w
);
664 printf("fn_6 ...\n");
665 w
= fn_6(42,43,44,45,46,47);
666 printf(" ... %d\n\n", (int)w
);
668 printf("fn_7 ...\n");
669 w
= fn_7(42,43,44,45,46,47,48);
670 printf(" ... %d\n\n", (int)w
);
672 printf("fn_8 ...\n");
673 w
= fn_8(42,43,44,45,46,47,48,49);
674 printf(" ... %d\n\n", (int)w
);
676 printf("fn_9 ...\n");
677 w
= fn_9(42,43,44,45,46,47,48,49,50);
678 printf(" ... %d\n\n", (int)w
);
680 printf("fn_10 ...\n");
681 w
= fn_10(42,43,44,45,46,47,48,49,50,51);
682 printf(" ... %d\n\n", (int)w
);
684 printf("fn_11 ...\n");
685 w
= fn_11(42,43,44,45,46,47,48,49,50,51,52);
686 printf(" ... %d\n\n", (int)w
);
688 printf("fn_12 ...\n");
689 w
= fn_12(42,43,44,45,46,47,48,49,50,51,52,53);
690 printf(" ... %d\n\n", (int)w
);