12d4be7aaSRichard Lowe /*
22d4be7aaSRichard Lowe  * This file and its contents are supplied under the terms of the
32d4be7aaSRichard Lowe  * Common Development and Distribution License ("CDDL"), version 1.0.
42d4be7aaSRichard Lowe  * You may only use this file in accordance with the terms of version
52d4be7aaSRichard Lowe  * 1.0 of the CDDL.
62d4be7aaSRichard Lowe  *
72d4be7aaSRichard Lowe  * A full copy of the text of the CDDL should have accompanied this
82d4be7aaSRichard Lowe  * source.  A copy of the CDDL is also available via the Internet at
92d4be7aaSRichard Lowe  * http://www.illumos.org/license/CDDL.
102d4be7aaSRichard Lowe  */
112d4be7aaSRichard Lowe 
122d4be7aaSRichard Lowe /*
132d4be7aaSRichard Lowe  * Copyright 2012, Richard Lowe.
142d4be7aaSRichard Lowe  */
152d4be7aaSRichard Lowe 
162d4be7aaSRichard Lowe #include <stdio.h>
172d4be7aaSRichard Lowe #include <sys/types.h>
182d4be7aaSRichard Lowe #include <saveargs.h>
192d4be7aaSRichard Lowe 
202d4be7aaSRichard Lowe #define	DEF_TEST(name)		\
212d4be7aaSRichard Lowe     extern uint8_t name[];	\
222d4be7aaSRichard Lowe     extern int name##_end
232d4be7aaSRichard Lowe 
242d4be7aaSRichard Lowe #define	SIZE_OF(name) ((caddr_t)&name##_end - (caddr_t)&name)
252d4be7aaSRichard Lowe 
262d4be7aaSRichard Lowe #define	TEST_GOOD(name, argc)					\
27*702941cdSRichard Lowe 	if (saveargs_has_args(name, SIZE_OF(name), argc, 0) ==	\
28*702941cdSRichard Lowe 	    SAVEARGS_TRAD_ARGS)					\
29*702941cdSRichard Lowe 		printf("Pass: %s\n", #name);			\
30*702941cdSRichard Lowe 	else							\
31*702941cdSRichard Lowe 		printf("FAIL: %s\n", #name);
322d4be7aaSRichard Lowe 
332d4be7aaSRichard Lowe #define	TEST_GOOD_STRUCT(name, argc)				\
34*702941cdSRichard Lowe 	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) ==	\
35*702941cdSRichard Lowe 	    SAVEARGS_STRUCT_ARGS)				\
36*702941cdSRichard Lowe 		printf("Pass: %s\n", #name);			\
37*702941cdSRichard Lowe 	else							\
38*702941cdSRichard Lowe 		printf("FAIL: %s\n", #name);
39*702941cdSRichard Lowe 
40*702941cdSRichard Lowe /*
41*702941cdSRichard Lowe  * GCC deals with structures differently, so TRAD args is actually correct for
42*702941cdSRichard Lowe  * this
43*702941cdSRichard Lowe  */
44*702941cdSRichard Lowe #define	TEST_GOOD_GSTRUCT(name, argc)				\
45*702941cdSRichard Lowe 	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) ==	\
46*702941cdSRichard Lowe 	    SAVEARGS_TRAD_ARGS)					\
47*702941cdSRichard Lowe 		printf("Pass: %s\n", #name);			\
48*702941cdSRichard Lowe 	else							\
49*702941cdSRichard Lowe 		printf("FAIL: %s\n", #name);
502d4be7aaSRichard Lowe 
512d4be7aaSRichard Lowe #define	TEST_BAD(name, argc)					\
52*702941cdSRichard Lowe 	if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == 	\
53*702941cdSRichard Lowe 		SAVEARGS_NO_ARGS)				\
54*702941cdSRichard Lowe 		printf("Pass: %s\n", #name);			\
55*702941cdSRichard Lowe 	else							\
56*702941cdSRichard Lowe 		printf("FAIL: %s\n", #name);
572d4be7aaSRichard Lowe 
582d4be7aaSRichard Lowe #define	TEST_BAD_STRUCT(name, argc)				\
59*702941cdSRichard Lowe 	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == 	\
60*702941cdSRichard Lowe 		SAVEARGS_NO_ARGS)				\
61*702941cdSRichard Lowe 		printf("Pass: %s\n", #name);			\
62*702941cdSRichard Lowe 	else							\
63*702941cdSRichard Lowe 		printf("FAIL: %s\n", #name);
64*702941cdSRichard Lowe 
65*702941cdSRichard Lowe #define	TEST_BAD_GSTRUCT(name, argc)				\
66*702941cdSRichard Lowe 	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == 	\
67*702941cdSRichard Lowe 		SAVEARGS_NO_ARGS)				\
68*702941cdSRichard Lowe 		printf("Pass: %s\n", #name);			\
69*702941cdSRichard Lowe 	else							\
70*702941cdSRichard Lowe 		printf("FAIL: %s\n", #name);
712d4be7aaSRichard Lowe 
722d4be7aaSRichard Lowe DEF_TEST(gcc_mov_align);
732d4be7aaSRichard Lowe DEF_TEST(gcc_mov_basic);
74*702941cdSRichard Lowe DEF_TEST(gcc_mov_noorder);
75*702941cdSRichard Lowe DEF_TEST(gcc_mov_struct_noorder);
762d4be7aaSRichard Lowe DEF_TEST(gcc_mov_big_struct_ret);
772d4be7aaSRichard Lowe DEF_TEST(gcc_mov_big_struct_ret_and_spill);
782d4be7aaSRichard Lowe DEF_TEST(gcc_mov_small_struct_ret);
792d4be7aaSRichard Lowe DEF_TEST(gcc_mov_small_struct_ret_and_spill);
802d4be7aaSRichard Lowe DEF_TEST(gcc_mov_stack_spill);
812d4be7aaSRichard Lowe 
822d4be7aaSRichard Lowe DEF_TEST(gcc_push_align);
832d4be7aaSRichard Lowe DEF_TEST(gcc_push_basic);
84*702941cdSRichard Lowe DEF_TEST(gcc_push_noorder);
85*702941cdSRichard Lowe DEF_TEST(gcc_push_struct_noorder);
862d4be7aaSRichard Lowe DEF_TEST(gcc_push_big_struct_ret);
872d4be7aaSRichard Lowe DEF_TEST(gcc_push_big_struct_ret_and_spill);
882d4be7aaSRichard Lowe DEF_TEST(gcc_push_small_struct_ret);
892d4be7aaSRichard Lowe DEF_TEST(gcc_push_small_struct_ret_and_spill);
902d4be7aaSRichard Lowe DEF_TEST(gcc_push_stack_spill);
912d4be7aaSRichard Lowe 
922d4be7aaSRichard Lowe DEF_TEST(ss_mov_align);
932d4be7aaSRichard Lowe DEF_TEST(ss_mov_basic);
942d4be7aaSRichard Lowe DEF_TEST(ss_mov_big_struct_ret);
952d4be7aaSRichard Lowe DEF_TEST(ss_mov_big_struct_ret_and_spill);
962d4be7aaSRichard Lowe DEF_TEST(ss_mov_small_struct_ret);
972d4be7aaSRichard Lowe DEF_TEST(ss_mov_small_struct_ret_and_spill);
982d4be7aaSRichard Lowe DEF_TEST(ss_mov_stack_spill);
992d4be7aaSRichard Lowe 
1002d4be7aaSRichard Lowe DEF_TEST(dtrace_instrumented);
1012d4be7aaSRichard Lowe DEF_TEST(kmem_alloc);
1022d4be7aaSRichard Lowe DEF_TEST(uts_kill);
1032d4be7aaSRichard Lowe DEF_TEST(av1394_ic_bitreverse);
1042d4be7aaSRichard Lowe 
1052d4be7aaSRichard Lowe DEF_TEST(small_struct_ret_w_float);
1062d4be7aaSRichard Lowe DEF_TEST(big_struct_ret_w_float);
1072d4be7aaSRichard Lowe 
108*702941cdSRichard Lowe DEF_TEST(interleaved_argument_saves);
109*702941cdSRichard Lowe DEF_TEST(jmp_table);
110*702941cdSRichard Lowe 
1112d4be7aaSRichard Lowe /*
1122d4be7aaSRichard Lowe  * Functions which should not match
1132d4be7aaSRichard Lowe  *
1142d4be7aaSRichard Lowe  * no_fp			-- valid save-args sequence with no saved FP
1152d4be7aaSRichard Lowe  * big_struct_arg_by_value	-- function with big struct passed by value
1162d4be7aaSRichard Lowe  * small_struct_arg_by_value	-- function with small struct passed by value
1172d4be7aaSRichard Lowe  */
1182d4be7aaSRichard Lowe DEF_TEST(no_fp);
1192d4be7aaSRichard Lowe DEF_TEST(big_struct_arg_by_value);
1202d4be7aaSRichard Lowe DEF_TEST(small_struct_arg_by_value);
1212d4be7aaSRichard Lowe 
1222d4be7aaSRichard Lowe int
main(int argc,char ** argv)1232d4be7aaSRichard Lowe main(int argc, char **argv)
1242d4be7aaSRichard Lowe {
1252d4be7aaSRichard Lowe 	TEST_GOOD(kmem_alloc, 2);
1262d4be7aaSRichard Lowe 	TEST_GOOD(uts_kill, 2);
1272d4be7aaSRichard Lowe 	TEST_GOOD(av1394_ic_bitreverse, 1);
1282d4be7aaSRichard Lowe 	TEST_GOOD(dtrace_instrumented, 4);
129*702941cdSRichard Lowe 	TEST_GOOD_GSTRUCT(big_struct_ret_w_float, 1);
1302d4be7aaSRichard Lowe 	TEST_BAD(no_fp, 5);
1312d4be7aaSRichard Lowe 
1322d4be7aaSRichard Lowe 	TEST_GOOD(gcc_mov_align, 5);
1332d4be7aaSRichard Lowe 	TEST_GOOD(gcc_push_align, 5);
1342d4be7aaSRichard Lowe 	TEST_GOOD(ss_mov_align, 5);
1352d4be7aaSRichard Lowe 
1362d4be7aaSRichard Lowe 	TEST_GOOD(gcc_mov_basic, 4);
1372d4be7aaSRichard Lowe 	TEST_GOOD(gcc_push_basic, 4);
1382d4be7aaSRichard Lowe 	TEST_GOOD(ss_mov_basic, 4);
1392d4be7aaSRichard Lowe 
140*702941cdSRichard Lowe 	TEST_GOOD(gcc_mov_noorder, 4);
141*702941cdSRichard Lowe 	TEST_GOOD(gcc_push_noorder, 4);
142*702941cdSRichard Lowe 
143*702941cdSRichard Lowe 	TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret, 4);
144*702941cdSRichard Lowe 	TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret, 4);
1452d4be7aaSRichard Lowe 	TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4);
1462d4be7aaSRichard Lowe 
147*702941cdSRichard Lowe 	TEST_GOOD_GSTRUCT(gcc_mov_struct_noorder, 4);
148*702941cdSRichard Lowe 	TEST_GOOD_GSTRUCT(gcc_push_struct_noorder, 4);
149*702941cdSRichard Lowe 
150*702941cdSRichard Lowe 	TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret_and_spill, 8);
151*702941cdSRichard Lowe 	TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret_and_spill, 8);
1522d4be7aaSRichard Lowe 	TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8);
1532d4be7aaSRichard Lowe 
1542d4be7aaSRichard Lowe 	TEST_GOOD(gcc_mov_small_struct_ret, 4);
1552d4be7aaSRichard Lowe 	TEST_GOOD(gcc_push_small_struct_ret, 4);
1562d4be7aaSRichard Lowe 	TEST_GOOD(ss_mov_small_struct_ret, 4);
1572d4be7aaSRichard Lowe 
1582d4be7aaSRichard Lowe 	TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8);
1592d4be7aaSRichard Lowe 	TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8);
1602d4be7aaSRichard Lowe 	TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8);
1612d4be7aaSRichard Lowe 
1622d4be7aaSRichard Lowe 	TEST_GOOD(gcc_mov_stack_spill, 8);
1632d4be7aaSRichard Lowe 	TEST_GOOD(gcc_push_stack_spill, 8);
1642d4be7aaSRichard Lowe 	TEST_GOOD(ss_mov_stack_spill, 8);
1652d4be7aaSRichard Lowe 
1662d4be7aaSRichard Lowe 	TEST_BAD(big_struct_arg_by_value, 2);
1672d4be7aaSRichard Lowe 	TEST_BAD(small_struct_arg_by_value, 2);
1682d4be7aaSRichard Lowe 
1692d4be7aaSRichard Lowe 	TEST_BAD(small_struct_ret_w_float, 1);
1702d4be7aaSRichard Lowe 
171*702941cdSRichard Lowe 	TEST_GOOD(interleaved_argument_saves, 4);
172*702941cdSRichard Lowe 	TEST_BAD(jmp_table, 1);
173*702941cdSRichard Lowe 
1742d4be7aaSRichard Lowe 	return (0);
1752d4be7aaSRichard Lowe }
176