12d4be7aRichard Lowe/*
22d4be7aRichard Lowe * This file and its contents are supplied under the terms of the
32d4be7aRichard Lowe * Common Development and Distribution License ("CDDL"), version 1.0.
42d4be7aRichard Lowe * You may only use this file in accordance with the terms of version
52d4be7aRichard Lowe * 1.0 of the CDDL.
62d4be7aRichard Lowe *
72d4be7aRichard Lowe * A full copy of the text of the CDDL should have accompanied this
82d4be7aRichard Lowe * source.  A copy of the CDDL is also available via the Internet at
92d4be7aRichard Lowe * http://www.illumos.org/license/CDDL.
102d4be7aRichard Lowe */
112d4be7aRichard Lowe
122d4be7aRichard Lowe/*
132d4be7aRichard Lowe * Copyright 2012, Richard Lowe.
142d4be7aRichard Lowe */
152d4be7aRichard Lowe
162d4be7aRichard Lowe#include <stdio.h>
172d4be7aRichard Lowe#include <sys/types.h>
182d4be7aRichard Lowe#include <saveargs.h>
192d4be7aRichard Lowe
202d4be7aRichard Lowe#define	DEF_TEST(name)		\
212d4be7aRichard Lowe    extern uint8_t name[];	\
222d4be7aRichard Lowe    extern int name##_end
232d4be7aRichard Lowe
242d4be7aRichard Lowe#define	SIZE_OF(name) ((caddr_t)&name##_end - (caddr_t)&name)
252d4be7aRichard Lowe
262d4be7aRichard Lowe#define	TEST_GOOD(name, argc)					\
27702941cRichard Lowe	if (saveargs_has_args(name, SIZE_OF(name), argc, 0) ==	\
28702941cRichard Lowe	    SAVEARGS_TRAD_ARGS)					\
29702941cRichard Lowe		printf("Pass: %s\n", #name);			\
30702941cRichard Lowe	else							\
31702941cRichard Lowe		printf("FAIL: %s\n", #name);
322d4be7aRichard Lowe
332d4be7aRichard Lowe#define	TEST_GOOD_STRUCT(name, argc)				\
34702941cRichard Lowe	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) ==	\
35702941cRichard Lowe	    SAVEARGS_STRUCT_ARGS)				\
36702941cRichard Lowe		printf("Pass: %s\n", #name);			\
37702941cRichard Lowe	else							\
38702941cRichard Lowe		printf("FAIL: %s\n", #name);
39702941cRichard Lowe
40702941cRichard Lowe/*
41702941cRichard Lowe * GCC deals with structures differently, so TRAD args is actually correct for
42702941cRichard Lowe * this
43702941cRichard Lowe */
44702941cRichard Lowe#define	TEST_GOOD_GSTRUCT(name, argc)				\
45702941cRichard Lowe	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) ==	\
46702941cRichard Lowe	    SAVEARGS_TRAD_ARGS)					\
47702941cRichard Lowe		printf("Pass: %s\n", #name);			\
48702941cRichard Lowe	else							\
49702941cRichard Lowe		printf("FAIL: %s\n", #name);
502d4be7aRichard Lowe
512d4be7aRichard Lowe#define	TEST_BAD(name, argc)					\
52702941cRichard Lowe	if (saveargs_has_args(name, SIZE_OF(name), argc, 0) == 	\
53702941cRichard Lowe		SAVEARGS_NO_ARGS)				\
54702941cRichard Lowe		printf("Pass: %s\n", #name);			\
55702941cRichard Lowe	else							\
56702941cRichard Lowe		printf("FAIL: %s\n", #name);
572d4be7aRichard Lowe
582d4be7aRichard Lowe#define	TEST_BAD_STRUCT(name, argc)				\
59702941cRichard Lowe	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == 	\
60702941cRichard Lowe		SAVEARGS_NO_ARGS)				\
61702941cRichard Lowe		printf("Pass: %s\n", #name);			\
62702941cRichard Lowe	else							\
63702941cRichard Lowe		printf("FAIL: %s\n", #name);
64702941cRichard Lowe
65702941cRichard Lowe#define	TEST_BAD_GSTRUCT(name, argc)				\
66702941cRichard Lowe	if (saveargs_has_args(name, SIZE_OF(name), argc, 1) == 	\
67702941cRichard Lowe		SAVEARGS_NO_ARGS)				\
68702941cRichard Lowe		printf("Pass: %s\n", #name);			\
69702941cRichard Lowe	else							\
70702941cRichard Lowe		printf("FAIL: %s\n", #name);
712d4be7aRichard Lowe
722d4be7aRichard LoweDEF_TEST(gcc_mov_align);
732d4be7aRichard LoweDEF_TEST(gcc_mov_basic);
74702941cRichard LoweDEF_TEST(gcc_mov_noorder);
75702941cRichard LoweDEF_TEST(gcc_mov_struct_noorder);
762d4be7aRichard LoweDEF_TEST(gcc_mov_big_struct_ret);
772d4be7aRichard LoweDEF_TEST(gcc_mov_big_struct_ret_and_spill);
782d4be7aRichard LoweDEF_TEST(gcc_mov_small_struct_ret);
792d4be7aRichard LoweDEF_TEST(gcc_mov_small_struct_ret_and_spill);
802d4be7aRichard LoweDEF_TEST(gcc_mov_stack_spill);
812d4be7aRichard Lowe
822d4be7aRichard LoweDEF_TEST(gcc_push_align);
832d4be7aRichard LoweDEF_TEST(gcc_push_basic);
84702941cRichard LoweDEF_TEST(gcc_push_noorder);
85702941cRichard LoweDEF_TEST(gcc_push_struct_noorder);
862d4be7aRichard LoweDEF_TEST(gcc_push_big_struct_ret);
872d4be7aRichard LoweDEF_TEST(gcc_push_big_struct_ret_and_spill);
882d4be7aRichard LoweDEF_TEST(gcc_push_small_struct_ret);
892d4be7aRichard LoweDEF_TEST(gcc_push_small_struct_ret_and_spill);
902d4be7aRichard LoweDEF_TEST(gcc_push_stack_spill);
912d4be7aRichard Lowe
922d4be7aRichard LoweDEF_TEST(ss_mov_align);
932d4be7aRichard LoweDEF_TEST(ss_mov_basic);
942d4be7aRichard LoweDEF_TEST(ss_mov_big_struct_ret);
952d4be7aRichard LoweDEF_TEST(ss_mov_big_struct_ret_and_spill);
962d4be7aRichard LoweDEF_TEST(ss_mov_small_struct_ret);
972d4be7aRichard LoweDEF_TEST(ss_mov_small_struct_ret_and_spill);
982d4be7aRichard LoweDEF_TEST(ss_mov_stack_spill);
992d4be7aRichard Lowe
1002d4be7aRichard LoweDEF_TEST(dtrace_instrumented);
1012d4be7aRichard LoweDEF_TEST(kmem_alloc);
1022d4be7aRichard LoweDEF_TEST(uts_kill);
1032d4be7aRichard LoweDEF_TEST(av1394_ic_bitreverse);
1042d4be7aRichard Lowe
1052d4be7aRichard LoweDEF_TEST(small_struct_ret_w_float);
1062d4be7aRichard LoweDEF_TEST(big_struct_ret_w_float);
1072d4be7aRichard Lowe
108702941cRichard LoweDEF_TEST(interleaved_argument_saves);
109702941cRichard LoweDEF_TEST(jmp_table);
110702941cRichard Lowe
1112d4be7aRichard Lowe/*
1122d4be7aRichard Lowe * Functions which should not match
1132d4be7aRichard Lowe *
1142d4be7aRichard Lowe * no_fp			-- valid save-args sequence with no saved FP
1152d4be7aRichard Lowe * big_struct_arg_by_value	-- function with big struct passed by value
1162d4be7aRichard Lowe * small_struct_arg_by_value	-- function with small struct passed by value
1172d4be7aRichard Lowe */
1182d4be7aRichard LoweDEF_TEST(no_fp);
1192d4be7aRichard LoweDEF_TEST(big_struct_arg_by_value);
1202d4be7aRichard LoweDEF_TEST(small_struct_arg_by_value);
1212d4be7aRichard Lowe
1222d4be7aRichard Loweint
1232d4be7aRichard Lowemain(int argc, char **argv)
1242d4be7aRichard Lowe{
1252d4be7aRichard Lowe	TEST_GOOD(kmem_alloc, 2);
1262d4be7aRichard Lowe	TEST_GOOD(uts_kill, 2);
1272d4be7aRichard Lowe	TEST_GOOD(av1394_ic_bitreverse, 1);
1282d4be7aRichard Lowe	TEST_GOOD(dtrace_instrumented, 4);
129702941cRichard Lowe	TEST_GOOD_GSTRUCT(big_struct_ret_w_float, 1);
1302d4be7aRichard Lowe	TEST_BAD(no_fp, 5);
1312d4be7aRichard Lowe
1322d4be7aRichard Lowe	TEST_GOOD(gcc_mov_align, 5);
1332d4be7aRichard Lowe	TEST_GOOD(gcc_push_align, 5);
1342d4be7aRichard Lowe	TEST_GOOD(ss_mov_align, 5);
1352d4be7aRichard Lowe
1362d4be7aRichard Lowe	TEST_GOOD(gcc_mov_basic, 4);
1372d4be7aRichard Lowe	TEST_GOOD(gcc_push_basic, 4);
1382d4be7aRichard Lowe	TEST_GOOD(ss_mov_basic, 4);
1392d4be7aRichard Lowe
140702941cRichard Lowe	TEST_GOOD(gcc_mov_noorder, 4);
141702941cRichard Lowe	TEST_GOOD(gcc_push_noorder, 4);
142702941cRichard Lowe
143702941cRichard Lowe	TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret, 4);
144702941cRichard Lowe	TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret, 4);
1452d4be7aRichard Lowe	TEST_GOOD_STRUCT(ss_mov_big_struct_ret, 4);
1462d4be7aRichard Lowe
147702941cRichard Lowe	TEST_GOOD_GSTRUCT(gcc_mov_struct_noorder, 4);
148702941cRichard Lowe	TEST_GOOD_GSTRUCT(gcc_push_struct_noorder, 4);
149702941cRichard Lowe
150702941cRichard Lowe	TEST_GOOD_GSTRUCT(gcc_mov_big_struct_ret_and_spill, 8);
151702941cRichard Lowe	TEST_GOOD_GSTRUCT(gcc_push_big_struct_ret_and_spill, 8);
1522d4be7aRichard Lowe	TEST_GOOD_STRUCT(ss_mov_big_struct_ret_and_spill, 8);
1532d4be7aRichard Lowe
1542d4be7aRichard Lowe	TEST_GOOD(gcc_mov_small_struct_ret, 4);
1552d4be7aRichard Lowe	TEST_GOOD(gcc_push_small_struct_ret, 4);
1562d4be7aRichard Lowe	TEST_GOOD(ss_mov_small_struct_ret, 4);
1572d4be7aRichard Lowe
1582d4be7aRichard Lowe	TEST_GOOD(gcc_mov_small_struct_ret_and_spill, 8);
1592d4be7aRichard Lowe	TEST_GOOD(gcc_push_small_struct_ret_and_spill, 8);
1602d4be7aRichard Lowe	TEST_GOOD(ss_mov_small_struct_ret_and_spill, 8);
1612d4be7aRichard Lowe
1622d4be7aRichard Lowe	TEST_GOOD(gcc_mov_stack_spill, 8);
1632d4be7aRichard Lowe	TEST_GOOD(gcc_push_stack_spill, 8);
1642d4be7aRichard Lowe	TEST_GOOD(ss_mov_stack_spill, 8);
1652d4be7aRichard Lowe
1662d4be7aRichard Lowe	TEST_BAD(big_struct_arg_by_value, 2);
1672d4be7aRichard Lowe	TEST_BAD(small_struct_arg_by_value, 2);
1682d4be7aRichard Lowe
1692d4be7aRichard Lowe	TEST_BAD(small_struct_ret_w_float, 1);
1702d4be7aRichard Lowe
171702941cRichard Lowe	TEST_GOOD(interleaved_argument_saves, 4);
172702941cRichard Lowe	TEST_BAD(jmp_table, 1);
173702941cRichard Lowe
1742d4be7aRichard Lowe	return (0);
1752d4be7aRichard Lowe}
176