1*bfa72590SIlya Leoshkevich /* Check EXECUTE with relative branch instructions as targets. */
2*bfa72590SIlya Leoshkevich #include <assert.h>
3*bfa72590SIlya Leoshkevich #include <stdbool.h>
4*bfa72590SIlya Leoshkevich #include <stdio.h>
5*bfa72590SIlya Leoshkevich #include <stdlib.h>
6*bfa72590SIlya Leoshkevich #include <string.h>
7*bfa72590SIlya Leoshkevich
8*bfa72590SIlya Leoshkevich struct test {
9*bfa72590SIlya Leoshkevich const char *name;
10*bfa72590SIlya Leoshkevich void (*func)(long *link, long *magic);
11*bfa72590SIlya Leoshkevich long exp_link;
12*bfa72590SIlya Leoshkevich };
13*bfa72590SIlya Leoshkevich
14*bfa72590SIlya Leoshkevich /* Branch instructions and their expected effects. */
15*bfa72590SIlya Leoshkevich #define LINK_64(test) ((long)test ## _exp_link)
16*bfa72590SIlya Leoshkevich #define LINK_NONE(test) -1L
17*bfa72590SIlya Leoshkevich #define FOR_EACH_INSN(F) \
18*bfa72590SIlya Leoshkevich F(bras, "%[link]", LINK_64) \
19*bfa72590SIlya Leoshkevich F(brasl, "%[link]", LINK_64) \
20*bfa72590SIlya Leoshkevich F(brc, "0x8", LINK_NONE) \
21*bfa72590SIlya Leoshkevich F(brcl, "0x8", LINK_NONE) \
22*bfa72590SIlya Leoshkevich F(brct, "%%r0", LINK_NONE) \
23*bfa72590SIlya Leoshkevich F(brctg, "%%r0", LINK_NONE) \
24*bfa72590SIlya Leoshkevich F(brxh, "%%r2,%%r0", LINK_NONE) \
25*bfa72590SIlya Leoshkevich F(brxhg, "%%r2,%%r0", LINK_NONE) \
26*bfa72590SIlya Leoshkevich F(brxle, "%%r0,%%r1", LINK_NONE) \
27*bfa72590SIlya Leoshkevich F(brxlg, "%%r0,%%r1", LINK_NONE) \
28*bfa72590SIlya Leoshkevich F(crj, "%%r0,%%r0,8", LINK_NONE) \
29*bfa72590SIlya Leoshkevich F(cgrj, "%%r0,%%r0,8", LINK_NONE) \
30*bfa72590SIlya Leoshkevich F(cij, "%%r0,0,8", LINK_NONE) \
31*bfa72590SIlya Leoshkevich F(cgij, "%%r0,0,8", LINK_NONE) \
32*bfa72590SIlya Leoshkevich F(clrj, "%%r0,%%r0,8", LINK_NONE) \
33*bfa72590SIlya Leoshkevich F(clgrj, "%%r0,%%r0,8", LINK_NONE) \
34*bfa72590SIlya Leoshkevich F(clij, "%%r0,0,8", LINK_NONE) \
35*bfa72590SIlya Leoshkevich F(clgij, "%%r0,0,8", LINK_NONE)
36*bfa72590SIlya Leoshkevich
37*bfa72590SIlya Leoshkevich #define INIT_TEST \
38*bfa72590SIlya Leoshkevich "xgr %%r0,%%r0\n" /* %r0 = 0; %cc = 0 */ \
39*bfa72590SIlya Leoshkevich "lghi %%r1,1\n" /* %r1 = 1 */ \
40*bfa72590SIlya Leoshkevich "lghi %%r2,2\n" /* %r2 = 2 */
41*bfa72590SIlya Leoshkevich
42*bfa72590SIlya Leoshkevich #define CLOBBERS_TEST "cc", "0", "1", "2"
43*bfa72590SIlya Leoshkevich
44*bfa72590SIlya Leoshkevich #define DEFINE_TEST(insn, args, exp_link) \
45*bfa72590SIlya Leoshkevich extern char insn ## _exp_link[]; \
46*bfa72590SIlya Leoshkevich static void test_ ## insn(long *link, long *magic) \
47*bfa72590SIlya Leoshkevich { \
48*bfa72590SIlya Leoshkevich asm(INIT_TEST \
49*bfa72590SIlya Leoshkevich #insn " " args ",0f\n" \
50*bfa72590SIlya Leoshkevich ".globl " #insn "_exp_link\n" \
51*bfa72590SIlya Leoshkevich #insn "_exp_link:\n" \
52*bfa72590SIlya Leoshkevich ".org . + 90\n" \
53*bfa72590SIlya Leoshkevich "0: lgfi %[magic],0x12345678\n" \
54*bfa72590SIlya Leoshkevich : [link] "+r" (*link) \
55*bfa72590SIlya Leoshkevich , [magic] "+r" (*magic) \
56*bfa72590SIlya Leoshkevich : : CLOBBERS_TEST); \
57*bfa72590SIlya Leoshkevich } \
58*bfa72590SIlya Leoshkevich extern char ex_ ## insn ## _exp_link[]; \
59*bfa72590SIlya Leoshkevich static void test_ex_ ## insn(long *link, long *magic) \
60*bfa72590SIlya Leoshkevich { \
61*bfa72590SIlya Leoshkevich unsigned long target; \
62*bfa72590SIlya Leoshkevich \
63*bfa72590SIlya Leoshkevich asm(INIT_TEST \
64*bfa72590SIlya Leoshkevich "larl %[target],0f\n" \
65*bfa72590SIlya Leoshkevich "ex %%r0,0(%[target])\n" \
66*bfa72590SIlya Leoshkevich ".globl ex_" #insn "_exp_link\n" \
67*bfa72590SIlya Leoshkevich "ex_" #insn "_exp_link:\n" \
68*bfa72590SIlya Leoshkevich ".org . + 60\n" \
69*bfa72590SIlya Leoshkevich "0: " #insn " " args ",1f\n" \
70*bfa72590SIlya Leoshkevich ".org . + 120\n" \
71*bfa72590SIlya Leoshkevich "1: lgfi %[magic],0x12345678\n" \
72*bfa72590SIlya Leoshkevich : [target] "=r" (target) \
73*bfa72590SIlya Leoshkevich , [link] "+r" (*link) \
74*bfa72590SIlya Leoshkevich , [magic] "+r" (*magic) \
75*bfa72590SIlya Leoshkevich : : CLOBBERS_TEST); \
76*bfa72590SIlya Leoshkevich } \
77*bfa72590SIlya Leoshkevich extern char exrl_ ## insn ## _exp_link[]; \
78*bfa72590SIlya Leoshkevich static void test_exrl_ ## insn(long *link, long *magic) \
79*bfa72590SIlya Leoshkevich { \
80*bfa72590SIlya Leoshkevich asm(INIT_TEST \
81*bfa72590SIlya Leoshkevich "exrl %%r0,0f\n" \
82*bfa72590SIlya Leoshkevich ".globl exrl_" #insn "_exp_link\n" \
83*bfa72590SIlya Leoshkevich "exrl_" #insn "_exp_link:\n" \
84*bfa72590SIlya Leoshkevich ".org . + 60\n" \
85*bfa72590SIlya Leoshkevich "0: " #insn " " args ",1f\n" \
86*bfa72590SIlya Leoshkevich ".org . + 120\n" \
87*bfa72590SIlya Leoshkevich "1: lgfi %[magic],0x12345678\n" \
88*bfa72590SIlya Leoshkevich : [link] "+r" (*link) \
89*bfa72590SIlya Leoshkevich , [magic] "+r" (*magic) \
90*bfa72590SIlya Leoshkevich : : CLOBBERS_TEST); \
91*bfa72590SIlya Leoshkevich }
92*bfa72590SIlya Leoshkevich
93*bfa72590SIlya Leoshkevich /* Test functions. */
94*bfa72590SIlya Leoshkevich FOR_EACH_INSN(DEFINE_TEST)
95*bfa72590SIlya Leoshkevich
96*bfa72590SIlya Leoshkevich /* Test definitions. */
97*bfa72590SIlya Leoshkevich #define REGISTER_TEST(insn, args, _exp_link) \
98*bfa72590SIlya Leoshkevich { \
99*bfa72590SIlya Leoshkevich .name = #insn, \
100*bfa72590SIlya Leoshkevich .func = test_ ## insn, \
101*bfa72590SIlya Leoshkevich .exp_link = (_exp_link(insn)), \
102*bfa72590SIlya Leoshkevich }, \
103*bfa72590SIlya Leoshkevich { \
104*bfa72590SIlya Leoshkevich .name = "ex " #insn, \
105*bfa72590SIlya Leoshkevich .func = test_ex_ ## insn, \
106*bfa72590SIlya Leoshkevich .exp_link = (_exp_link(ex_ ## insn)), \
107*bfa72590SIlya Leoshkevich }, \
108*bfa72590SIlya Leoshkevich { \
109*bfa72590SIlya Leoshkevich .name = "exrl " #insn, \
110*bfa72590SIlya Leoshkevich .func = test_exrl_ ## insn, \
111*bfa72590SIlya Leoshkevich .exp_link = (_exp_link(exrl_ ## insn)), \
112*bfa72590SIlya Leoshkevich },
113*bfa72590SIlya Leoshkevich
114*bfa72590SIlya Leoshkevich static const struct test tests[] = {
115*bfa72590SIlya Leoshkevich FOR_EACH_INSN(REGISTER_TEST)
116*bfa72590SIlya Leoshkevich };
117*bfa72590SIlya Leoshkevich
main(int argc,char ** argv)118*bfa72590SIlya Leoshkevich int main(int argc, char **argv)
119*bfa72590SIlya Leoshkevich {
120*bfa72590SIlya Leoshkevich const struct test *test;
121*bfa72590SIlya Leoshkevich int ret = EXIT_SUCCESS;
122*bfa72590SIlya Leoshkevich bool verbose = false;
123*bfa72590SIlya Leoshkevich long link, magic;
124*bfa72590SIlya Leoshkevich size_t i;
125*bfa72590SIlya Leoshkevich
126*bfa72590SIlya Leoshkevich for (i = 1; i < argc; i++) {
127*bfa72590SIlya Leoshkevich if (strcmp(argv[i], "-v") == 0) {
128*bfa72590SIlya Leoshkevich verbose = true;
129*bfa72590SIlya Leoshkevich }
130*bfa72590SIlya Leoshkevich }
131*bfa72590SIlya Leoshkevich
132*bfa72590SIlya Leoshkevich for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
133*bfa72590SIlya Leoshkevich test = &tests[i];
134*bfa72590SIlya Leoshkevich if (verbose) {
135*bfa72590SIlya Leoshkevich fprintf(stderr, "[ RUN ] %s\n", test->name);
136*bfa72590SIlya Leoshkevich }
137*bfa72590SIlya Leoshkevich link = -1;
138*bfa72590SIlya Leoshkevich magic = -1;
139*bfa72590SIlya Leoshkevich test->func(&link, &magic);
140*bfa72590SIlya Leoshkevich #define ASSERT_EQ(expected, actual) do { \
141*bfa72590SIlya Leoshkevich if (expected != actual) { \
142*bfa72590SIlya Leoshkevich fprintf(stderr, "%s: " #expected " (0x%lx) != " #actual " (0x%lx)\n", \
143*bfa72590SIlya Leoshkevich test->name, expected, actual); \
144*bfa72590SIlya Leoshkevich ret = EXIT_FAILURE; \
145*bfa72590SIlya Leoshkevich } \
146*bfa72590SIlya Leoshkevich } while (0)
147*bfa72590SIlya Leoshkevich ASSERT_EQ(test->exp_link, link);
148*bfa72590SIlya Leoshkevich ASSERT_EQ(0x12345678L, magic);
149*bfa72590SIlya Leoshkevich #undef ASSERT_EQ
150*bfa72590SIlya Leoshkevich }
151*bfa72590SIlya Leoshkevich
152*bfa72590SIlya Leoshkevich if (verbose) {
153*bfa72590SIlya Leoshkevich fprintf(stderr, ret == EXIT_SUCCESS ? "[ PASSED ]\n" :
154*bfa72590SIlya Leoshkevich "[ FAILED ]\n");
155*bfa72590SIlya Leoshkevich }
156*bfa72590SIlya Leoshkevich
157*bfa72590SIlya Leoshkevich return ret;
158*bfa72590SIlya Leoshkevich }
159