1*b41e2fb6SRichard Lowe /*
2*b41e2fb6SRichard Lowe * This file and its contents are supplied under the terms of the
3*b41e2fb6SRichard Lowe * Common Development and Distribution License ("CDDL"), version 1.0.
4*b41e2fb6SRichard Lowe * You may only use this file in accordance with the terms of version
5*b41e2fb6SRichard Lowe * 1.0 of the CDDL.
6*b41e2fb6SRichard Lowe *
7*b41e2fb6SRichard Lowe * A full copy of the text of the CDDL should have accompanied this
8*b41e2fb6SRichard Lowe * source. A copy of the CDDL is also available via the Internet at
9*b41e2fb6SRichard Lowe * http://www.illumos.org/license/CDDL.
10*b41e2fb6SRichard Lowe */
11*b41e2fb6SRichard Lowe
12*b41e2fb6SRichard Lowe /*
13*b41e2fb6SRichard Lowe * Copyright 2012, Richard Lowe.
14*b41e2fb6SRichard Lowe */
15*b41e2fb6SRichard Lowe
16*b41e2fb6SRichard Lowe #include <stdio.h>
17*b41e2fb6SRichard Lowe #include <sys/types.h>
18*b41e2fb6SRichard Lowe #include <saveargs.h>
19*b41e2fb6SRichard Lowe
20*b41e2fb6SRichard Lowe #define DEF_TEST(name) \
21*b41e2fb6SRichard Lowe extern uint8_t name[]; \
22*b41e2fb6SRichard Lowe extern int name##_end
23*b41e2fb6SRichard Lowe
24*b41e2fb6SRichard Lowe #define SIZE_OF(name) ((caddr_t)&name##_end - (caddr_t)&name)
25*b41e2fb6SRichard Lowe
26*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_align);
27*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_basic);
28*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_noorder);
29*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_struct_noorder);
30*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_big_struct_ret);
31*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_big_struct_ret_and_spill);
32*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_small_struct_ret);
33*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_small_struct_ret_and_spill);
34*b41e2fb6SRichard Lowe DEF_TEST(gcc_mov_stack_spill);
35*b41e2fb6SRichard Lowe
36*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_align);
37*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_basic);
38*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_noorder);
39*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_struct_noorder);
40*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_big_struct_ret);
41*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_big_struct_ret_and_spill);
42*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_small_struct_ret);
43*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_small_struct_ret_and_spill);
44*b41e2fb6SRichard Lowe DEF_TEST(gcc_push_stack_spill);
45*b41e2fb6SRichard Lowe
46*b41e2fb6SRichard Lowe DEF_TEST(ss_mov_align);
47*b41e2fb6SRichard Lowe DEF_TEST(ss_mov_basic);
48*b41e2fb6SRichard Lowe DEF_TEST(ss_mov_big_struct_ret);
49*b41e2fb6SRichard Lowe DEF_TEST(ss_mov_big_struct_ret_and_spill);
50*b41e2fb6SRichard Lowe DEF_TEST(ss_mov_small_struct_ret);
51*b41e2fb6SRichard Lowe DEF_TEST(ss_mov_small_struct_ret_and_spill);
52*b41e2fb6SRichard Lowe DEF_TEST(ss_mov_stack_spill);
53*b41e2fb6SRichard Lowe
54*b41e2fb6SRichard Lowe DEF_TEST(dtrace_instrumented);
55*b41e2fb6SRichard Lowe DEF_TEST(kmem_alloc);
56*b41e2fb6SRichard Lowe DEF_TEST(uts_kill);
57*b41e2fb6SRichard Lowe DEF_TEST(av1394_ic_bitreverse);
58*b41e2fb6SRichard Lowe
59*b41e2fb6SRichard Lowe DEF_TEST(small_struct_ret_w_float);
60*b41e2fb6SRichard Lowe DEF_TEST(big_struct_ret_w_float);
61*b41e2fb6SRichard Lowe
62*b41e2fb6SRichard Lowe DEF_TEST(interleaved_argument_saves);
63*b41e2fb6SRichard Lowe DEF_TEST(jmp_table);
64*b41e2fb6SRichard Lowe
65*b41e2fb6SRichard Lowe /*
66*b41e2fb6SRichard Lowe * Functions which should not match
67*b41e2fb6SRichard Lowe *
68*b41e2fb6SRichard Lowe * no_fp -- valid save-args sequence with no saved FP
69*b41e2fb6SRichard Lowe * big_struct_arg_by_value -- function with big struct passed by value
70*b41e2fb6SRichard Lowe * small_struct_arg_by_value -- function with small struct passed by value
71*b41e2fb6SRichard Lowe */
72*b41e2fb6SRichard Lowe DEF_TEST(no_fp);
73*b41e2fb6SRichard Lowe DEF_TEST(big_struct_arg_by_value);
74*b41e2fb6SRichard Lowe DEF_TEST(small_struct_arg_by_value);
75*b41e2fb6SRichard Lowe
76*b41e2fb6SRichard Lowe int
main(int argc,char ** argv)77*b41e2fb6SRichard Lowe main(int argc, char **argv)
78*b41e2fb6SRichard Lowe {
79*b41e2fb6SRichard Lowe
80*b41e2fb6SRichard Lowe #define TEST_GOOD(name, argc) \
81*b41e2fb6SRichard Lowe do { \
82*b41e2fb6SRichard Lowe if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == \
83*b41e2fb6SRichard Lowe SAVEARGS_TRAD_ARGS) { \
84*b41e2fb6SRichard Lowe printf("Pass: %s\n", #name); \
85*b41e2fb6SRichard Lowe } else { \
86*b41e2fb6SRichard Lowe res = 1; \
87*b41e2fb6SRichard Lowe printf("FAIL: %s\n", #name); \
88*b41e2fb6SRichard Lowe } \
89*b41e2fb6SRichard Lowe } while (0)
90*b41e2fb6SRichard Lowe
91*b41e2fb6SRichard Lowe #define TEST_GOOD_STRUCT(name, argc) \
92*b41e2fb6SRichard Lowe do { \
93*b41e2fb6SRichard Lowe if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \
94*b41e2fb6SRichard Lowe SAVEARGS_STRUCT_ARGS) { \
95*b41e2fb6SRichard Lowe printf("Pass: %s\n", #name); \
96*b41e2fb6SRichard Lowe } else { \
97*b41e2fb6SRichard Lowe res = 1; \
98*b41e2fb6SRichard Lowe printf("FAIL: %s\n", #name); \
99*b41e2fb6SRichard Lowe } \
100*b41e2fb6SRichard Lowe } while (0)
101*b41e2fb6SRichard Lowe
102*b41e2fb6SRichard Lowe /*
103*b41e2fb6SRichard Lowe * GCC deals with structures differently, so TRAD args is actually correct for
104*b41e2fb6SRichard Lowe * this
105*b41e2fb6SRichard Lowe */
106*b41e2fb6SRichard Lowe #define TEST_GOOD_GSTRUCT(name, argc) \
107*b41e2fb6SRichard Lowe do { \
108*b41e2fb6SRichard Lowe if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \
109*b41e2fb6SRichard Lowe SAVEARGS_TRAD_ARGS) { \
110*b41e2fb6SRichard Lowe printf("Pass: %s\n", #name); \
111*b41e2fb6SRichard Lowe } else { \
112*b41e2fb6SRichard Lowe res = 1; \
113*b41e2fb6SRichard Lowe printf("FAIL: %s\n", #name); \
114*b41e2fb6SRichard Lowe } \
115*b41e2fb6SRichard Lowe } while (0)
116*b41e2fb6SRichard Lowe
117*b41e2fb6SRichard Lowe #define TEST_BAD(name, argc) \
118*b41e2fb6SRichard Lowe do { \
119*b41e2fb6SRichard Lowe if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == \
120*b41e2fb6SRichard Lowe SAVEARGS_NO_ARGS) { \
121*b41e2fb6SRichard Lowe printf("Pass: %s\n", #name); \
122*b41e2fb6SRichard Lowe } else { \
123*b41e2fb6SRichard Lowe res = 1; \
124*b41e2fb6SRichard Lowe printf("FAIL: %s\n", #name); \
125*b41e2fb6SRichard Lowe } \
126*b41e2fb6SRichard Lowe } while (0)
127*b41e2fb6SRichard Lowe
128*b41e2fb6SRichard Lowe #define TEST_BAD_STRUCT(name, argc) \
129*b41e2fb6SRichard Lowe do { \
130*b41e2fb6SRichard Lowe if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \
131*b41e2fb6SRichard Lowe SAVEARGS_NO_ARGS) { \
132*b41e2fb6SRichard Lowe printf("Pass: %s\n", #name); \
133*b41e2fb6SRichard Lowe } else { \
134*b41e2fb6SRichard Lowe res = 1; \
135*b41e2fb6SRichard Lowe printf("FAIL: %s\n", #name); \
136*b41e2fb6SRichard Lowe } \
137*b41e2fb6SRichard Lowe } while (0)
138*b41e2fb6SRichard Lowe
139*b41e2fb6SRichard Lowe #define TEST_BAD_GSTRUCT(name, argc) \
140*b41e2fb6SRichard Lowe do { \
141*b41e2fb6SRichard Lowe if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == \
142*b41e2fb6SRichard Lowe SAVEARGS_NO_ARGS) { \
143*b41e2fb6SRichard Lowe printf("Pass: %s\n", #name); \
144*b41e2fb6SRichard Lowe } else { \
145*b41e2fb6SRichard Lowe res = 1; \
146*b41e2fb6SRichard Lowe printf("FAIL: %s\n", #name); \
147*b41e2fb6SRichard Lowe } \
148*b41e2fb6SRichard Lowe } while (0)
149*b41e2fb6SRichard Lowe
150*b41e2fb6SRichard Lowe int res = 0;
151*b41e2fb6SRichard Lowe
152*b41e2fb6SRichard Lowe TEST_GOOD(kmem_alloc, 2);
153*b41e2fb6SRichard Lowe TEST_GOOD(uts_kill, 2);
154*b41e2fb6SRichard Lowe TEST_GOOD(av1394_ic_bitreverse, 1);
155*b41e2fb6SRichard Lowe TEST_GOOD(dtrace_instrumented, 4);
156*b41e2fb6SRichard Lowe TEST_GOOD_GSTRUCT(big_struct_ret_w_float, 1);
157*b41e2fb6SRichard Lowe TEST_BAD(no_fp, 5);
158*b41e2fb6SRichard Lowe
159*b41e2fb6SRichard Lowe TEST_GOOD(gcc_mov_align, 5);
160*b41e2fb6SRichard Lowe TEST_GOOD(gcc_push_align, 5);
161*b41e2fb6SRichard Lowe TEST_GOOD(ss_mov_align, 5);
162*b41e2fb6SRichard Lowe
163*b41e2fb6SRichard Lowe TEST_GOOD(gcc_mov_basic, 4);
164*b41e2fb6SRichard Lowe TEST_GOOD(gcc_push_basic, 4);
165*b41e2fb6SRichard Lowe TEST_GOOD(ss_mov_basic, 4);
166*b41e2fb6SRichard Lowe
167*b41e2fb6SRichard Lowe TEST_GOOD(gcc_mov_noorder, 4);
168*b41e2fb6SRichard Lowe TEST_GOOD(gcc_push_noorder, 4);
169*b41e2fb6SRichard Lowe
170*b41e2fb6SRichard Lowe TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret, 4);
171*b41e2fb6SRichard Lowe TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret, 4);
172*b41e2fb6SRichard Lowe TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4);
173*b41e2fb6SRichard Lowe
174*b41e2fb6SRichard Lowe TEST_GOOD_GSTRUCT(gcc_mov_struct_noorder, 4);
175*b41e2fb6SRichard Lowe TEST_GOOD_GSTRUCT(gcc_push_struct_noorder, 4);
176*b41e2fb6SRichard Lowe
177*b41e2fb6SRichard Lowe TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret_and_spill, 8);
178*b41e2fb6SRichard Lowe TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret_and_spill, 8);
179*b41e2fb6SRichard Lowe TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8);
180*b41e2fb6SRichard Lowe
181*b41e2fb6SRichard Lowe TEST_GOOD(gcc_mov_small_struct_ret, 4);
182*b41e2fb6SRichard Lowe TEST_GOOD(gcc_push_small_struct_ret, 4);
183*b41e2fb6SRichard Lowe TEST_GOOD(ss_mov_small_struct_ret, 4);
184*b41e2fb6SRichard Lowe
185*b41e2fb6SRichard Lowe TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8);
186*b41e2fb6SRichard Lowe TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8);
187*b41e2fb6SRichard Lowe TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8);
188*b41e2fb6SRichard Lowe
189*b41e2fb6SRichard Lowe TEST_GOOD(gcc_mov_stack_spill, 8);
190*b41e2fb6SRichard Lowe TEST_GOOD(gcc_push_stack_spill, 8);
191*b41e2fb6SRichard Lowe TEST_GOOD(ss_mov_stack_spill, 8);
192*b41e2fb6SRichard Lowe
193*b41e2fb6SRichard Lowe TEST_BAD(big_struct_arg_by_value, 2);
194*b41e2fb6SRichard Lowe
195*b41e2fb6SRichard Lowe TEST_BAD_STRUCT(small_struct_ret_w_float, 1);
196*b41e2fb6SRichard Lowe
197*b41e2fb6SRichard Lowe TEST_GOOD(interleaved_argument_saves, 4);
198*b41e2fb6SRichard Lowe TEST_BAD(jmp_table, 1);
199*b41e2fb6SRichard Lowe
200*b41e2fb6SRichard Lowe return (res);
201*b41e2fb6SRichard Lowe }
202