master
c 112 lines 2.2 KB
Raw
1 #include <assert.h>
2 #include <signal.h>
3 #include <stdint.h>
4
5 /* Set asynchronously by the signal handler. */
6 static volatile int signum;
7
8 static void signal_handler(int n)
9 {
10 signum = n;
11 }
12
13 static void test_dr(void)
14 {
15 register int32_t r0 asm("r0") = -1;
16 register int32_t r1 asm("r1") = -4241;
17 int32_t b = 101, q, r;
18
19 asm("dr %[r0],%[b]"
20 : [r0] "+r" (r0), [r1] "+r" (r1)
21 : [b] "r" (b)
22 : "cc");
23 q = r1;
24 r = r0;
25 assert(q == -41);
26 assert(r == -100);
27 }
28
29 static void test_dlr(void)
30 {
31 register uint32_t r0 asm("r0") = 0;
32 register uint32_t r1 asm("r1") = 4243;
33 uint32_t b = 101, q, r;
34
35 asm("dlr %[r0],%[b]"
36 : [r0] "+r" (r0), [r1] "+r" (r1)
37 : [b] "r" (b)
38 : "cc");
39 q = r1;
40 r = r0;
41 assert(q == 42);
42 assert(r == 1);
43 }
44
45 static void test_dsgr(void)
46 {
47 register int64_t r0 asm("r0") = -1;
48 register int64_t r1 asm("r1") = -4241;
49 int64_t b = 101, q, r;
50
51 asm("dsgr %[r0],%[b]"
52 : [r0] "+r" (r0), [r1] "+r" (r1)
53 : [b] "r" (b)
54 : "cc");
55 q = r1;
56 r = r0;
57 assert(q == -41);
58 assert(r == -100);
59 }
60
61 static void test_dlgr(void)
62 {
63 register uint64_t r0 asm("r0") = 0;
64 register uint64_t r1 asm("r1") = 4243;
65 uint64_t b = 101, q, r;
66
67 asm("dlgr %[r0],%[b]"
68 : [r0] "+r" (r0), [r1] "+r" (r1)
69 : [b] "r" (b)
70 : "cc");
71 q = r1;
72 r = r0;
73 assert(q == 42);
74 assert(r == 1);
75 }
76
77 /*
78 * The most negative dividend divided by -1 yields a quotient that does not
79 * fit into 32 bits, so DR must raise a fixed-point-divide exception.
80 */
81 static void test_dr_overflow(void)
82 {
83 struct sigaction act = { .sa_handler = signal_handler };
84 register int32_t r0 asm("r0");
85 register int32_t r1 asm("r1");
86 int32_t b = -1;
87 int err;
88
89 err = sigaction(SIGFPE, &act, NULL);
90 assert(err == 0);
91 signum = -1;
92
93 r0 = 0x80000000;
94 r1 = 0;
95 asm volatile("dr %[r0],%[b]"
96 : [r0] "+r" (r0), [r1] "+r" (r1)
97 : [b] "r" (b)
98 : "cc");
99 assert(signum == SIGFPE);
100
101 signal(SIGFPE, SIG_DFL);
102 }
103
104 int main(void)
105 {
106 test_dr();
107 test_dlr();
108 test_dsgr();
109 test_dlgr();
110 test_dr_overflow();
111 return 0;
112 }