1 #if defined(__mips_hard_float)
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
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)
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
[] = {
46 const double fs_d
[] = {
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
[] = {
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
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
74 __asm__ volatile(op" %1, %2, %3" "\n\t" \
75 "cfc1 %0, $31" "\n\t" \
76 : "=r" (fcsr), "=f"(fd) \
81 __asm__ volatile(op" %1, %2" "\n\t" \
82 "cfc1 %0, $31" "\n\t" \
83 : "=r" (fcsr), "=f"(fd_d) \
88 __asm__ volatile(op" %1, %2" "\n\t" \
89 "cfc1 %0, $31" "\n\t" \
90 : "=r" (fcsr), "=f"(fd_f) \
95 __asm__ volatile(op" %1, %2" "\n\t" \
96 "cfc1 %0, $31" "\n\t" \
97 : "=r" (fcsr), "=f"(fd_d) \
102 __asm__ volatile(op" %1, %2" "\n\t" \
103 "cfc1 %0, $31" "\n\t" \
104 : "=r" (fcsr), "=f"(fd_f) \
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) \
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) \
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) \
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) \
143 void set_rounding_mode(round_mode_t mode
)
147 __asm__
volatile("ctc1 $zero, $31" "\n\t");
150 __asm__
volatile("li $t0, 0x1" "\n\t"
151 "ctc1 $t0, $31" "\n\t");
153 case TO_PLUS_INFINITY
:
154 __asm__
volatile("li $t0, 0x2" "\n\t"
155 "ctc1 $t0, $31" "\n\t");
157 case TO_MINUS_INFINITY
:
158 __asm__
volatile("li $t0, 0x3" "\n\t"
159 "ctc1 $t0, $31" "\n\t");
165 __asm__
__volatile__(
166 "cfc1 $t0, $31" "\n\t"
167 "and $t0, $t0, 0x17FFFFF" "\n\t"
168 "ctc1 $t0, $31" "\n\t"
175 int directedRoundingMode(flt_dir_op_t op
) {
179 round_mode_t rm
= TO_NEAREST
;
180 for (i
= 0; i
< 24; i
++) {
182 set_rounding_mode(rm
);
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
232 int FCSRRoundingMode(flt_round_op_t op1
)
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
++) {
245 set_rounding_mode(rm
);
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
));
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
));
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
));
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
));
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
));
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
));
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
);