none/tests/fdleak_cmsg_supp.supp: Add suppressions for older glibc
[valgrind.git] / none / tests / mips32 / round.c
blob052508da39107be969b89a396a31b1c8ebe816de
1 #if defined(__mips_hard_float)
3 #include <stdio.h>
5 /*
6 * Bits 18 (NAN2008) and 19 (ABS2008) are preset by hardware and may differ
7 * between platforms. Hence a macro to clear them before printing FCSR
8 * values.
9 */
10 #define FCSR_NAN2008 1 << 18
11 #define FCSR_ABS2008 1 << 19
12 #define FLAGS_RM_MASK 0xFFFFFFFF & ~(FCSR_ABS2008 | FCSR_NAN2008)
13 #define CLEAR_PRESETBITS_FCSR(fcsr) (fcsr & FLAGS_RM_MASK)
15 typedef enum {
16 CEILWS=0, CEILWD,
17 FLOORWS, FLOORWD,
18 ROUNDWS, ROUNDWD,
19 TRUNCWS, TRUNCWD
20 } flt_dir_op_t;
22 typedef enum {
23 CVTDS, CVTDW,
24 CVTSD, CVTSW,
25 CVTWS, CVTWD
26 } flt_round_op_t;
28 typedef enum {
29 TO_NEAREST=0, TO_ZERO, TO_PLUS_INFINITY, TO_MINUS_INFINITY } round_mode_t;
30 char *round_mode_name[] = { "near", "zero", "+inf", "-inf" };
33 const char *flt_dir_op_names[] = {
34 "ceil.w.s", "ceil.w.d",
35 "floor.w.s", "floor.w.d",
36 "round.w.s", "round.w.d",
37 "trunc.w.s", "trunc.w.d"
40 const char *flt_round_op_names[] = {
41 "cvt.d.s", "cvt.d.w",
42 "cvt.s.d", "cvt.s.w",
43 "cvt.w.s", "cvt.w.d"
46 const double fs_d[] = {
47 0, 456.25, 3, -1,
48 1384.5, -7.25, 1000000000, -5786.25,
49 1752, 0.015625, 0.03125, -248562.75,
50 -45786.5, 456, 34.03125, 45786.75,
51 1752065, 107, -45667.25, -7,
52 -347856.5, 356047, -1.25, 23.0625
55 const float fs_f[] = {
56 0, 456.25, 3, -1,
57 1384.5, -7.25, 1000000000, -5786.25,
58 1752, 0.015625, 0.03125, -248562.75,
59 -45786.5, 456, 34.03125, 45786.75,
60 1752065, 107, -45667.25, -7,
61 -347856.5, 356047, -1.25, 23.0625
64 const int fs_w[] = {
65 0, 456, 3, -1,
66 0xffffffff, 356, 1000000000, -5786,
67 1752, 24575, 10, -248562,
68 -45786, 456, 34, 45786,
69 1752065, 107, -45667, -7,
70 -347856, 0x80000000, 0xFFFFFFF, 23
73 #define BINOP(op) \
74 __asm__ volatile(op" %1, %2, %3" "\n\t" \
75 "cfc1 %0, $31" "\n\t" \
76 : "=r" (fcsr), "=f"(fd) \
77 : "f"(f) , "f"(fB));
79 #define UNOPdd(op) \
80 fd_d = 0; \
81 __asm__ volatile(op" %1, %2" "\n\t" \
82 "cfc1 %0, $31" "\n\t" \
83 : "=r" (fcsr), "=f"(fd_d) \
84 : "f"(fs_d[i]));
86 #define UNOPff(op) \
87 fd_f = 0; \
88 __asm__ volatile(op" %1, %2" "\n\t" \
89 "cfc1 %0, $31" "\n\t" \
90 : "=r" (fcsr), "=f"(fd_f) \
91 : "f"(fs_f[i]));
93 #define UNOPfd(op) \
94 fd_d = 0; \
95 __asm__ volatile(op" %1, %2" "\n\t" \
96 "cfc1 %0, $31" "\n\t" \
97 : "=r" (fcsr), "=f"(fd_d) \
98 : "f"(fs_f[i]));
100 #define UNOPdf(op) \
101 fd_f = 0; \
102 __asm__ volatile(op" %1, %2" "\n\t" \
103 "cfc1 %0, $31" "\n\t" \
104 : "=r" (fcsr), "=f"(fd_f) \
105 : "f"(fs_d[i]));
107 #define UNOPfw(op) \
108 fd_w = 0; \
109 __asm__ volatile(op" $f0, %2" "\n\t" \
110 "mfc1 %1, $f0" "\n\t" \
111 "cfc1 %0, $31" "\n\t" \
112 : "=r" (fcsr), "=r"(fd_w) \
113 : "f"(fs_f[i]) \
114 : "$f0");
116 #define UNOPdw(op) \
117 fd_w = 0; \
118 __asm__ volatile(op" $f0, %2" "\n\t" \
119 "mfc1 %1, $f0" "\n\t" \
120 "cfc1 %0, $31" "\n\t" \
121 : "=r" (fcsr), "=r"(fd_w) \
122 : "f"(fs_d[i]) \
123 : "$f0");
125 #define UNOPwd(op) \
126 fd_d = 0; \
127 __asm__ volatile("mtc1 %2, $f0" "\n\t" \
128 op" %1, $f0" "\n\t" \
129 "cfc1 %0, $31" "\n\t" \
130 : "=r" (fcsr), "=f"(fd_d) \
131 : "r"(fs_w[i]) \
132 : "$f0", "$f1");
134 #define UNOPwf(op) \
135 fd_f = 0; \
136 __asm__ volatile("mtc1 %2, $f0" "\n\t" \
137 op" %1, $f0" "\n\t" \
138 "cfc1 %0, $31" "\n\t" \
139 : "=r" (fcsr), "=f"(fd_f) \
140 : "r"(fs_w[i]) \
141 : "$f0");
143 void set_rounding_mode(round_mode_t mode)
145 switch(mode) {
146 case TO_NEAREST:
147 __asm__ volatile("ctc1 $zero, $31" "\n\t");
148 break;
149 case TO_ZERO:
150 __asm__ volatile("li $t0, 0x1" "\n\t"
151 "ctc1 $t0, $31" "\n\t");
152 break;
153 case TO_PLUS_INFINITY:
154 __asm__ volatile("li $t0, 0x2" "\n\t"
155 "ctc1 $t0, $31" "\n\t");
156 break;
157 case TO_MINUS_INFINITY:
158 __asm__ volatile("li $t0, 0x3" "\n\t"
159 "ctc1 $t0, $31" "\n\t");
160 break;
164 void clear_fcc(){
165 __asm__ __volatile__(
166 "cfc1 $t0, $31" "\n\t"
167 "and $t0, $t0, 0x17FFFFF" "\n\t"
168 "ctc1 $t0, $31" "\n\t"
171 : "t0"
175 int directedRoundingMode(flt_dir_op_t op) {
176 int fd_w = 0;
177 int i;
178 int fcsr = 0;
179 round_mode_t rm = TO_NEAREST;
180 for (i = 0; i < 24; i++) {
181 clear_fcc();
182 set_rounding_mode(rm);
183 switch(op) {
184 case CEILWS:
185 UNOPfw("ceil.w.s");
186 printf("%s %d %f\n", flt_dir_op_names[op], fd_w, fs_f[i]);
187 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
188 break;
189 case CEILWD:
190 UNOPdw("ceil.w.d");
191 printf("%s %d %lf\n", flt_dir_op_names[op], fd_w, fs_d[i]);
192 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
193 break;
194 case FLOORWS:
195 UNOPfw("floor.w.s");
196 printf("%s %d %f\n", flt_dir_op_names[op], fd_w, fs_f[i]);
197 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
198 break;
199 case FLOORWD:
200 UNOPdw("floor.w.d");
201 printf("%s %d %lf\n", flt_dir_op_names[op], fd_w, fs_d[i]);
202 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
203 break;
204 case ROUNDWS:
205 UNOPfw("round.w.s");
206 printf("%s %d %f\n", flt_dir_op_names[op], fd_w, fs_f[i]);
207 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
208 break;
209 case ROUNDWD:
210 UNOPdw("round.w.d");
211 printf("%s %d %lf\n", flt_dir_op_names[op], fd_w, fs_d[i]);
212 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
213 break;
214 case TRUNCWS:
215 UNOPfw("trunc.w.s");
216 printf("%s %d %f\n", flt_dir_op_names[op], fd_w, fs_f[i]);
217 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
218 break;
219 case TRUNCWD:
220 UNOPdw("trunc.w.d");
221 printf("%s %d %lf\n", flt_dir_op_names[op], fd_w, fs_d[i]);
222 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
223 break;
224 default:
225 printf("error\n");
226 break;
229 return 0;
232 int FCSRRoundingMode(flt_round_op_t op1)
234 double fd_d = 0;
235 float fd_f = 0;
236 int fd_w = 0;
237 int i;
238 int fcsr = 0;
239 round_mode_t rm;
240 for (rm = TO_NEAREST; rm <= TO_MINUS_INFINITY; rm ++) {
241 set_rounding_mode(rm);
242 printf("roundig mode: %s\n", round_mode_name[rm]);
243 for (i = 0; i < 24; i++) {
244 clear_fcc();
245 set_rounding_mode(rm);
246 switch(op1) {
247 case CVTDS:
248 UNOPfd("cvt.d.s");
249 printf("%s %lf %lf\n", flt_round_op_names[op1], fd_d, fs_f[i]);
250 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
251 break;
252 case CVTDW:
253 UNOPwd("cvt.d.w");
254 printf("%s %lf %d\n", flt_round_op_names[op1], fd_d, fs_w[i]);
255 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
256 break;
257 case CVTSD:
258 UNOPdf("cvt.s.d");
259 printf("%s %f %lf\n", flt_round_op_names[op1], fd_f, fs_d[i]);
260 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
261 break;
262 case CVTSW:
263 UNOPwf("cvt.s.w");
264 printf("%s %f %d\n", flt_round_op_names[op1], fd_f, fs_w[i]);
265 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
266 break;
267 case CVTWS:
268 UNOPfw("cvt.w.s");
269 printf("%s %d %f\n", flt_round_op_names[op1], fd_w, fs_f[i]);
270 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
271 break;
272 case CVTWD:
273 UNOPdw("cvt.w.d");
274 printf("%s %d %lf\n", flt_round_op_names[op1], fd_w, fs_d[i]);
275 printf("fcsr: 0x%x\n", CLEAR_PRESETBITS_FCSR(fcsr));
276 break;
277 default:
278 printf("error\n");
279 break;
283 return 0;
286 int main()
288 flt_dir_op_t op;
289 flt_round_op_t op1;
291 printf("-------------------------- %s --------------------------\n",
292 "test FPU Conversion Operations Using a Directed Rounding Mode");
293 for (op = CEILWS; op <= TRUNCWD; op++) {
294 directedRoundingMode(op);
297 printf("-------------------------- %s --------------------------\n",
298 "test FPU Conversion Operations Using the FCSR Rounding Mode");
299 for (op1 = CVTDS; op1 <= CVTWD; op1++) {
300 FCSRRoundingMode(op1);
302 return 0;
304 #else
305 int main() {
306 return 0;
308 #endif