blob: feba1685561e98e99f58926c66d31e4088c2cc19 [file] [log] [blame]
Elliott Hughesa0664b92017-04-18 17:46:52 -07001#if defined(__mips_hard_float)
2
sewardje584b0e2012-06-07 09:32:40 +00003#include <stdio.h>
4
5typedef enum {
6 CEILWS=0, CEILWD,
7 FLOORWS, FLOORWD,
8 ROUNDWS, ROUNDWD,
9 TRUNCWS, TRUNCWD
10} flt_dir_op_t;
11
12typedef enum {
13 CVTDS, CVTDW,
14 CVTSD, CVTSW,
15 CVTWS, CVTWD
16} flt_round_op_t;
17
18typedef enum {
19 TO_NEAREST=0, TO_ZERO, TO_PLUS_INFINITY, TO_MINUS_INFINITY } round_mode_t;
20char *round_mode_name[] = { "near", "zero", "+inf", "-inf" };
21
22
23const char *flt_dir_op_names[] = {
24 "ceil.w.s", "ceil.w.d",
25 "floor.w.s", "floor.w.d",
26 "round.w.s", "round.w.d",
27 "trunc.w.s", "trunc.w.d"
28};
29
30const char *flt_round_op_names[] = {
31 "cvt.d.s", "cvt.d.w",
32 "cvt.s.d", "cvt.s.w",
33 "cvt.w.s", "cvt.w.d"
34};
35
36const double fs_d[] = {
dejanj34ff1742013-12-05 14:05:25 +000037 0, 456.25, 3, -1,
38 1384.5, -7.25, 1000000000, -5786.25,
39 1752, 0.015625, 0.03125, -248562.75,
40 -45786.5, 456, 34.03125, 45786.75,
41 1752065, 107, -45667.25, -7,
dejanj8a9c20b2013-09-24 07:00:46 +000042 -347856.5, 356047, -1.25, 23.0625
sewardje584b0e2012-06-07 09:32:40 +000043};
44
45const float fs_f[] = {
dejanj8a9c20b2013-09-24 07:00:46 +000046 0, 456.25, 3, -1,
47 1384.5, -7.25, 1000000000, -5786.25,
48 1752, 0.015625, 0.03125, -248562.75,
49 -45786.5, 456, 34.03125, 45786.75,
50 1752065, 107, -45667.25, -7,
51 -347856.5, 356047, -1.25, 23.0625
sewardje584b0e2012-06-07 09:32:40 +000052};
53
54const int fs_w[] = {
55 0, 456, 3, -1,
56 0xffffffff, 356, 1000000000, -5786,
57 1752, 24575, 10, -248562,
58 -45786, 456, 34, 45786,
59 1752065, 107, -45667, -7,
dejanj8a9c20b2013-09-24 07:00:46 +000060 -347856, 0x80000000, 0xFFFFFFF, 23
sewardje584b0e2012-06-07 09:32:40 +000061};
62
dejanj4164a812013-09-18 10:08:23 +000063#define BINOP(op) \
64 __asm__ volatile(op" %1, %2, %3" "\n\t" \
65 "cfc1 %0, $31" "\n\t" \
66 : "=r" (fcsr), "=f"(fd) \
67 : "f"(f) , "f"(fB));
sewardje584b0e2012-06-07 09:32:40 +000068
dejanj4164a812013-09-18 10:08:23 +000069#define UNOPdd(op) \
70 fd_d = 0; \
71 __asm__ volatile(op" %1, %2" "\n\t" \
72 "cfc1 %0, $31" "\n\t" \
73 : "=r" (fcsr), "=f"(fd_d) \
74 : "f"(fs_d[i]));
sewardje584b0e2012-06-07 09:32:40 +000075
dejanj4164a812013-09-18 10:08:23 +000076#define UNOPff(op) \
77 fd_f = 0; \
78 __asm__ volatile(op" %1, %2" "\n\t" \
79 "cfc1 %0, $31" "\n\t" \
80 : "=r" (fcsr), "=f"(fd_f) \
81 : "f"(fs_f[i]));
sewardje584b0e2012-06-07 09:32:40 +000082
dejanj4164a812013-09-18 10:08:23 +000083#define UNOPfd(op) \
84 fd_d = 0; \
85 __asm__ volatile(op" %1, %2" "\n\t" \
86 "cfc1 %0, $31" "\n\t" \
87 : "=r" (fcsr), "=f"(fd_d) \
88 : "f"(fs_f[i]));
sewardje584b0e2012-06-07 09:32:40 +000089
dejanj4164a812013-09-18 10:08:23 +000090#define UNOPdf(op) \
91 fd_f = 0; \
92 __asm__ volatile(op" %1, %2" "\n\t" \
93 "cfc1 %0, $31" "\n\t" \
94 : "=r" (fcsr), "=f"(fd_f) \
95 : "f"(fs_d[i]));
sewardje584b0e2012-06-07 09:32:40 +000096
dejanj4164a812013-09-18 10:08:23 +000097#define UNOPfw(op) \
98 fd_w = 0; \
99 __asm__ volatile(op" $f0, %2" "\n\t" \
100 "mfc1 %1, $f0" "\n\t" \
101 "cfc1 %0, $31" "\n\t" \
102 : "=r" (fcsr), "=r"(fd_w) \
103 : "f"(fs_f[i]) \
104 : "$f0");
sewardje584b0e2012-06-07 09:32:40 +0000105
dejanj4164a812013-09-18 10:08:23 +0000106#define UNOPdw(op) \
107 fd_w = 0; \
108 __asm__ volatile(op" $f0, %2" "\n\t" \
109 "mfc1 %1, $f0" "\n\t" \
110 "cfc1 %0, $31" "\n\t" \
111 : "=r" (fcsr), "=r"(fd_w) \
112 : "f"(fs_d[i]) \
113 : "$f0");
sewardje584b0e2012-06-07 09:32:40 +0000114
dejanj4164a812013-09-18 10:08:23 +0000115#define UNOPwd(op) \
116 fd_d = 0; \
117 __asm__ volatile("mtc1 %2, $f0" "\n\t" \
118 op" %1, $f0" "\n\t" \
119 "cfc1 %0, $31" "\n\t" \
120 : "=r" (fcsr), "=f"(fd_d) \
121 : "r"(fs_w[i]) \
122 : "$f0", "$f1");
sewardje584b0e2012-06-07 09:32:40 +0000123
dejanj4164a812013-09-18 10:08:23 +0000124#define UNOPwf(op) \
125 fd_f = 0; \
126 __asm__ volatile("mtc1 %2, $f0" "\n\t" \
127 op" %1, $f0" "\n\t" \
128 "cfc1 %0, $31" "\n\t" \
129 : "=r" (fcsr), "=f"(fd_f) \
130 : "r"(fs_w[i]) \
131 : "$f0");
sewardje584b0e2012-06-07 09:32:40 +0000132
133void set_rounding_mode(round_mode_t mode)
134{
dejanj4164a812013-09-18 10:08:23 +0000135 switch(mode) {
136 case TO_NEAREST:
dejanj24f0c3a2014-02-19 11:57:22 +0000137 __asm__ volatile("ctc1 $zero, $31" "\n\t");
dejanj4164a812013-09-18 10:08:23 +0000138 break;
139 case TO_ZERO:
dejanj24f0c3a2014-02-19 11:57:22 +0000140 __asm__ volatile("li $t0, 0x1" "\n\t"
141 "ctc1 $t0, $31" "\n\t");
dejanj4164a812013-09-18 10:08:23 +0000142 break;
143 case TO_PLUS_INFINITY:
dejanj24f0c3a2014-02-19 11:57:22 +0000144 __asm__ volatile("li $t0, 0x2" "\n\t"
145 "ctc1 $t0, $31" "\n\t");
dejanj4164a812013-09-18 10:08:23 +0000146 break;
147 case TO_MINUS_INFINITY:
dejanj24f0c3a2014-02-19 11:57:22 +0000148 __asm__ volatile("li $t0, 0x3" "\n\t"
149 "ctc1 $t0, $31" "\n\t");
dejanj4164a812013-09-18 10:08:23 +0000150 break;
151 }
sewardje584b0e2012-06-07 09:32:40 +0000152}
153
Elliott Hughesa0664b92017-04-18 17:46:52 -0700154void clear_fcc(){
155 __asm__ __volatile__(
156 "cfc1 $t0, $31" "\n\t"
157 "and $t0, $t0, 0x17FFFFF" "\n\t"
158 "ctc1 $t0, $31" "\n\t"
159 :
160 :
161 : "t0"
162 );
163}
164
sewardje584b0e2012-06-07 09:32:40 +0000165int directedRoundingMode(flt_dir_op_t op) {
sewardje584b0e2012-06-07 09:32:40 +0000166 int fd_w = 0;
167 int i;
dejanj4164a812013-09-18 10:08:23 +0000168 int fcsr = 0;
dejanj34ff1742013-12-05 14:05:25 +0000169 round_mode_t rm = TO_NEAREST;
sewardje584b0e2012-06-07 09:32:40 +0000170 for (i = 0; i < 24; i++) {
Elliott Hughesa0664b92017-04-18 17:46:52 -0700171 clear_fcc();
dejanj34ff1742013-12-05 14:05:25 +0000172 set_rounding_mode(rm);
sewardje584b0e2012-06-07 09:32:40 +0000173 switch(op) {
174 case CEILWS:
175 UNOPfw("ceil.w.s");
176 printf("%s %d %f\n", flt_dir_op_names[op], fd_w, fs_f[i]);
dejanj4164a812013-09-18 10:08:23 +0000177 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000178 break;
179 case CEILWD:
180 UNOPdw("ceil.w.d");
181 printf("%s %d %lf\n", flt_dir_op_names[op], fd_w, fs_d[i]);
dejanj4164a812013-09-18 10:08:23 +0000182 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000183 break;
184 case FLOORWS:
185 UNOPfw("floor.w.s");
186 printf("%s %d %f\n", flt_dir_op_names[op], fd_w, fs_f[i]);
dejanj4164a812013-09-18 10:08:23 +0000187 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000188 break;
189 case FLOORWD:
190 UNOPdw("floor.w.d");
191 printf("%s %d %lf\n", flt_dir_op_names[op], fd_w, fs_d[i]);
dejanj4164a812013-09-18 10:08:23 +0000192 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000193 break;
194 case ROUNDWS:
195 UNOPfw("round.w.s");
196 printf("%s %d %f\n", flt_dir_op_names[op], fd_w, fs_f[i]);
dejanj4164a812013-09-18 10:08:23 +0000197 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000198 break;
199 case ROUNDWD:
200 UNOPdw("round.w.d");
201 printf("%s %d %lf\n", flt_dir_op_names[op], fd_w, fs_d[i]);
dejanj4164a812013-09-18 10:08:23 +0000202 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000203 break;
204 case TRUNCWS:
205 UNOPfw("trunc.w.s");
206 printf("%s %d %f\n", flt_dir_op_names[op], fd_w, fs_f[i]);
dejanj4164a812013-09-18 10:08:23 +0000207 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000208 break;
209 case TRUNCWD:
210 UNOPdw("trunc.w.d");
211 printf("%s %d %lf\n", flt_dir_op_names[op], fd_w, fs_d[i]);
dejanj4164a812013-09-18 10:08:23 +0000212 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000213 break;
214 default:
215 printf("error\n");
216 break;
217 }
218 }
219 return 0;
220}
221
dejanj34ff1742013-12-05 14:05:25 +0000222int FCSRRoundingMode(flt_round_op_t op1)
sewardje584b0e2012-06-07 09:32:40 +0000223{
224 double fd_d = 0;
225 float fd_f = 0;
226 int fd_w = 0;
227 int i;
dejanj4164a812013-09-18 10:08:23 +0000228 int fcsr = 0;
sewardje584b0e2012-06-07 09:32:40 +0000229 round_mode_t rm;
dejanj34ff1742013-12-05 14:05:25 +0000230 for (rm = TO_NEAREST; rm <= TO_MINUS_INFINITY; rm ++) {
sewardje584b0e2012-06-07 09:32:40 +0000231 set_rounding_mode(rm);
232 printf("roundig mode: %s\n", round_mode_name[rm]);
dejanj4164a812013-09-18 10:08:23 +0000233 for (i = 0; i < 24; i++) {
Elliott Hughesa0664b92017-04-18 17:46:52 -0700234 clear_fcc();
sewardje584b0e2012-06-07 09:32:40 +0000235 set_rounding_mode(rm);
236 switch(op1) {
237 case CVTDS:
238 UNOPfd("cvt.d.s");
239 printf("%s %lf %lf\n", flt_round_op_names[op1], fd_d, fs_f[i]);
dejanj4164a812013-09-18 10:08:23 +0000240 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000241 break;
242 case CVTDW:
243 UNOPwd("cvt.d.w");
244 printf("%s %lf %d\n", flt_round_op_names[op1], fd_d, fs_w[i]);
dejanj4164a812013-09-18 10:08:23 +0000245 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000246 break;
247 case CVTSD:
248 UNOPdf("cvt.s.d");
249 printf("%s %f %lf\n", flt_round_op_names[op1], fd_f, fs_d[i]);
dejanj4164a812013-09-18 10:08:23 +0000250 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000251 break;
252 case CVTSW:
253 UNOPwf("cvt.s.w");
254 printf("%s %f %d\n", flt_round_op_names[op1], fd_f, fs_w[i]);
dejanj4164a812013-09-18 10:08:23 +0000255 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000256 break;
257 case CVTWS:
258 UNOPfw("cvt.w.s");
259 printf("%s %d %f\n", flt_round_op_names[op1], fd_w, fs_f[i]);
dejanj4164a812013-09-18 10:08:23 +0000260 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000261 break;
262 case CVTWD:
263 UNOPdw("cvt.w.d");
264 printf("%s %d %lf\n", flt_round_op_names[op1], fd_w, fs_d[i]);
dejanj4164a812013-09-18 10:08:23 +0000265 printf("fcsr: 0x%x\n", fcsr);
sewardje584b0e2012-06-07 09:32:40 +0000266 break;
267 default:
268 printf("error\n");
269 break;
270 }
271 }
272 }
273 return 0;
274}
275
276int main()
277{
278 flt_dir_op_t op;
279 flt_round_op_t op1;
280
281 printf("-------------------------- %s --------------------------\n",
282 "test FPU Conversion Operations Using a Directed Rounding Mode");
283 for (op = CEILWS; op <= TRUNCWD; op++) {
284 directedRoundingMode(op);
285 }
dejanj34ff1742013-12-05 14:05:25 +0000286
sewardje584b0e2012-06-07 09:32:40 +0000287 printf("-------------------------- %s --------------------------\n",
288 "test FPU Conversion Operations Using the FCSR Rounding Mode");
289 for (op1 = CVTDS; op1 <= CVTWD; op1++) {
290 FCSRRoundingMode(op1);
291 }
292 return 0;
293}
Elliott Hughesa0664b92017-04-18 17:46:52 -0700294#else
295int main() {
296 return 0;
297}
298#endif
petarj4931c0d2012-07-16 14:07:47 +0000299