xref: /openbmc/qemu/tests/tcg/m68k/trap.c (revision a6caeee8)
1 /*
2  * Test m68k trap addresses.
3  */
4 
5 #define _GNU_SOURCE 1
6 #include <signal.h>
7 #include <assert.h>
8 #include <limits.h>
9 
10 static int expect_sig;
11 static int expect_si_code;
12 static void *expect_si_addr;
13 static greg_t expect_mc_pc;
14 static volatile int got_signal;
15 
16 static void sig_handler(int sig, siginfo_t *si, void *puc)
17 {
18     ucontext_t *uc = puc;
19     mcontext_t *mc = &uc->uc_mcontext;
20 
21     assert(sig == expect_sig);
22     assert(si->si_code == expect_si_code);
23     assert(si->si_addr == expect_si_addr);
24     assert(mc->gregs[R_PC] == expect_mc_pc);
25 
26     got_signal = 1;
27 }
28 
29 #define FMT_INS     [ad] "a"(&expect_si_addr), [pc] "a"(&expect_mc_pc)
30 #define FMT0_STR(S) \
31     "move.l #1f, (%[ad])\n\tmove.l #1f, (%[pc])\n" S "\n1:\n"
32 #define FMT2_STR(S) \
33     "move.l #0f, (%[ad])\n\tmove.l #1f, (%[pc])\n" S "\n1:\n"
34 
35 #define CHECK_SIG   do { assert(got_signal); got_signal = 0; } while (0)
36 
37 int main(int argc, char **argv)
38 {
39     struct sigaction act = {
40         .sa_sigaction = sig_handler,
41         .sa_flags = SA_SIGINFO
42     };
43     int t0, t1;
44 
45     sigaction(SIGILL, &act, NULL);
46     sigaction(SIGTRAP, &act, NULL);
47     sigaction(SIGFPE, &act, NULL);
48 
49     expect_sig = SIGFPE;
50     expect_si_code = FPE_INTOVF;
51     asm volatile(FMT2_STR("0:\tchk %0, %1") : : "d"(0), "d"(-1), FMT_INS);
52     CHECK_SIG;
53 
54 #if 0
55     /* FIXME: chk2 not correctly translated. */
56     int bounds[2] = { 0, 1 };
57     asm volatile(FMT2_STR("0:\tchk2.l %0, %1")
58                  : : "m"(bounds), "d"(2), FMT_INS);
59     CHECK_SIG;
60 #endif
61 
62     asm volatile(FMT2_STR("cmp.l %0, %1\n0:\ttrapv")
63                  : : "d"(INT_MIN), "d"(1), FMT_INS);
64     CHECK_SIG;
65 
66     asm volatile(FMT2_STR("cmp.l %0, %0\n0:\ttrapeq")
67                  : : "d"(0), FMT_INS);
68     CHECK_SIG;
69 
70     asm volatile(FMT2_STR("cmp.l %0, %0\n0:\ttrapeq.w #0x1234")
71                  : : "d"(0), FMT_INS);
72     CHECK_SIG;
73 
74     asm volatile(FMT2_STR("cmp.l %0, %0\n0:\ttrapeq.l #0x12345678")
75                  : : "d"(0), FMT_INS);
76     CHECK_SIG;
77 
78     asm volatile(FMT2_STR("fcmp.x %0, %0\n0:\tftrapeq")
79                  : : "f"(0.0L), FMT_INS);
80     CHECK_SIG;
81 
82     expect_si_code = FPE_INTDIV;
83 
84     asm volatile(FMT2_STR("0:\tdivs.w %1, %0")
85                  : "=d"(t0) : "d"(0), "0"(1), FMT_INS);
86     CHECK_SIG;
87 
88     asm volatile(FMT2_STR("0:\tdivsl.l %2, %1:%0")
89                  : "=d"(t0), "=d"(t1) : "d"(0), "0"(1), FMT_INS);
90     CHECK_SIG;
91 
92     expect_sig = SIGILL;
93     expect_si_code = ILL_ILLTRP;
94     asm volatile(FMT0_STR("trap #1") : : FMT_INS);
95     CHECK_SIG;
96     asm volatile(FMT0_STR("trap #2") : : FMT_INS);
97     CHECK_SIG;
98     asm volatile(FMT0_STR("trap #3") : : FMT_INS);
99     CHECK_SIG;
100     asm volatile(FMT0_STR("trap #4") : : FMT_INS);
101     CHECK_SIG;
102     asm volatile(FMT0_STR("trap #5") : : FMT_INS);
103     CHECK_SIG;
104     asm volatile(FMT0_STR("trap #6") : : FMT_INS);
105     CHECK_SIG;
106     asm volatile(FMT0_STR("trap #7") : : FMT_INS);
107     CHECK_SIG;
108     asm volatile(FMT0_STR("trap #8") : : FMT_INS);
109     CHECK_SIG;
110     asm volatile(FMT0_STR("trap #9") : : FMT_INS);
111     CHECK_SIG;
112     asm volatile(FMT0_STR("trap #10") : : FMT_INS);
113     CHECK_SIG;
114     asm volatile(FMT0_STR("trap #11") : : FMT_INS);
115     CHECK_SIG;
116     asm volatile(FMT0_STR("trap #12") : : FMT_INS);
117     CHECK_SIG;
118     asm volatile(FMT0_STR("trap #13") : : FMT_INS);
119     CHECK_SIG;
120     asm volatile(FMT0_STR("trap #14") : : FMT_INS);
121     CHECK_SIG;
122 
123     expect_sig = SIGTRAP;
124     expect_si_code = TRAP_BRKPT;
125     asm volatile(FMT0_STR("trap #15") : : FMT_INS);
126     CHECK_SIG;
127 
128     return 0;
129 }
130