1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <stdlib.h>
19#include <stdio.h>
20#include <unistd.h>
21#include <sys/types.h>
22#include <fcntl.h>
23#include <setjmp.h>
24#include <signal.h>
25
26
27int err;
28
29static void __check(const char *filename, int line, int x, int expect)
30{
31 if (x != expect) {
32 printf("ERROR %s:%d - %d != %d\n",
33 filename, line, x, expect);
34 err++;
35 }
36}
37
38#define check(x, expect) __check(__FILE__, __LINE__, (x), (expect))
39
40static int satub(int src, int *p, int *ovf_result)
41{
42 int result;
43 int usr;
44
45
46
47
48
49
50
51
52
53 asm volatile("r2 = usr\n\t"
54 "r2 = clrbit(r2, #0)\n\t"
55 "usr = r2\n\t"
56 "{\n\t"
57 " %0 = satub(%2)\n\t"
58 " memw(%3) = %2\n\t"
59 "}\n\t"
60 "%1 = usr\n\t"
61 : "=r"(result), "=r"(usr)
62 : "r"(src), "r"(p)
63 : "r2", "usr", "memory");
64 *ovf_result = (usr & 1);
65 return result;
66}
67
68int read_usr_overflow(void)
69{
70 int result;
71 asm volatile("%0 = usr\n\t" : "=r"(result));
72 return result & 1;
73}
74
75int get_usr_overflow(int usr)
76{
77 return usr & 1;
78}
79
80int get_usr_fp_invalid(int usr)
81{
82 return (usr >> 1) & 1;
83}
84
85int get_usr_lpcfg(int usr)
86{
87 return (usr >> 8) & 0x3;
88}
89
90jmp_buf jmp_env;
91int usr_overflow;
92
93static void sig_segv(int sig, siginfo_t *info, void *puc)
94{
95 usr_overflow = read_usr_overflow();
96 longjmp(jmp_env, 1);
97}
98
99static void test_packet(void)
100{
101 int convres;
102 int satres;
103 int usr;
104
105 asm("r2 = usr\n\t"
106 "r2 = clrbit(r2, #0)\n\t"
107 "r2 = clrbit(r2, #1)\n\t"
108 "usr = r2\n\t"
109 "{\n\t"
110 " %0 = convert_sf2uw(%3):chop\n\t"
111 " %1 = satb(%4)\n\t"
112 "}\n\t"
113 "%2 = usr\n\t"
114 : "=r"(convres), "=r"(satres), "=r"(usr)
115 : "r"(0x6a051b86), "r"(0x0410eec0)
116 : "r2", "usr");
117
118 check(convres, 0xffffffff);
119 check(satres, 0x7f);
120 check(get_usr_overflow(usr), 1);
121 check(get_usr_fp_invalid(usr), 1);
122
123 asm("r2 = usr\n\t"
124 "r2 = clrbit(r2, #0)\n\t"
125 "usr = r2\n\t"
126 "%2 = r2\n\t"
127 "p3 = sp3loop0(1f, #1)\n\t"
128 "1:\n\t"
129 "{\n\t"
130 " %0 = satb(%2)\n\t"
131 "}:endloop0\n\t"
132 "%1 = usr\n\t"
133 : "=r"(satres), "=r"(usr)
134 : "r"(0x0410eec0)
135 : "r2", "usr", "p3", "sa0", "lc0");
136
137 check(satres, 0x7f);
138 check(get_usr_overflow(usr), 1);
139 check(get_usr_lpcfg(usr), 2);
140}
141
142int main()
143{
144 struct sigaction act;
145 int ovf;
146
147
148 act.sa_sigaction = sig_segv;
149 sigemptyset(&act.sa_mask);
150 act.sa_flags = SA_SIGINFO;
151 sigaction(SIGSEGV, &act, NULL);
152 if (setjmp(jmp_env) == 0) {
153 satub(300, 0, &ovf);
154 }
155
156 act.sa_handler = SIG_DFL;
157 sigemptyset(&act.sa_mask);
158 act.sa_flags = 0;
159
160 check(usr_overflow, 0);
161
162 test_packet();
163
164 puts(err ? "FAIL" : "PASS");
165 return err ? EXIT_FAILURE : EXIT_SUCCESS;
166}
167