blob: 7b12c755bff7e35735c341342267b73714693728 [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>
dejanj34ff1742013-12-05 14:05:25 +00004#include <stdlib.h>
sewardje584b0e2012-06-07 09:32:40 +00005
6typedef enum {
7 ABSS=0, ABSD,
8 ADDS, ADDD,
9 DIVS, DIVD,
10 MULS, MULD,
11 NEGS, NEGD,
12 SQRTS, SQRTD,
13 SUBS, SUBD,
14 RECIPS, RECIPD,
15 RSQRTS, RSQRTD
16} flt_art_op_t;
17
18const char *flt_art_op_names[] = {
19 "abs.s", "abs.d",
20 "add.s", "add.d",
21 "div.s", "div.d",
22 "mul.s", "mul.d",
23 "neg.s", "neg.d",
24 "sqrt.s", "sqrt.d",
25 "sub.s", "sub.d",
26 "recip.s", "recip.d",
27 "rsqrt.s", "rsqrt.d"
28};
29
dejanj34ff1742013-12-05 14:05:25 +000030typedef enum {
31 TO_NEAREST=0, TO_ZERO, TO_PLUS_INFINITY, TO_MINUS_INFINITY } round_mode_t;
32char *round_mode_name[] = { "near", "zero", "+inf", "-inf" };
33
sewardje584b0e2012-06-07 09:32:40 +000034const double fs_d[] = {
dejanj34ff1742013-12-05 14:05:25 +000035 0, 456.25, 3, -1,
36 1384.5, -7.25, 1000000000, -5786.5,
37 1752, 0.015625, 0.03125, -248562.75,
38 456, -45786.5, 34.03125, 45786.75,
39 1752065, 107, -45667.25, -7,
40 -347856.5, 356047.5, -1.0, 23.0625
sewardje584b0e2012-06-07 09:32:40 +000041};
42
43const double ft_d[] = {
dejanj34ff1742013-12-05 14:05:25 +000044 -456.25, -45786.5, 34.03125, 45786.75,
45 1752065, 107, -45667.25, -7.25,
46 -347856.5, 356047.5, -1.0, 23.0625,
47 0, 456.25, 3, -1,
48 1384.5, -7, 1000000000, -5786.5,
49 1752, 0.015625, 0.03125, -248562.75
sewardje584b0e2012-06-07 09:32:40 +000050};
51
52const float fs_f[] = {
dejanj34ff1742013-12-05 14:05:25 +000053 0, 456.25, 3, -1,
54 1384.5, -7.25, 1000000000, -5786.5,
55 1752, 0.015625, 0.03125, -248562.75,
56 456, -45786.5, 34.03125, 45786.75,
57 1752065, 107, -45667.25, -7,
58 -347856.5, 356047.5, -1.0, 23.0625
sewardje584b0e2012-06-07 09:32:40 +000059};
60
61const float ft_f[] = {
dejanj34ff1742013-12-05 14:05:25 +000062 -456.25, -4578.5, 34.03125, 4578.75,
63 175, 107, -456.25, -7.25,
64 -3478.5, 356.5, -1.0, 23.0625,
65 0, 456.25, 3, -1,
66 1384.5, -7, 100, -5786.5,
67 1752, 0.015625, 0.03125, -248562.75
sewardje584b0e2012-06-07 09:32:40 +000068};
69
70#define UNOPdd(op) \
71 fd_d = 0; \
72 __asm__ volatile( \
73 op" %0, %1\n\t" \
74 : "=f"(fd_d) : "f"(fs_d[i]));
75
76#define UNOPff(op) \
77 fd_f = 0; \
78 __asm__ volatile( \
79 op" %0, %1\n\t" \
80 : "=f"(fd_f) : "f"(fs_f[i]));
81
82#define BINOPf(op) \
83 fd_f = 0; \
84 __asm__ volatile( \
85 op" %0, %1, %2\n\t" \
86 : "=f"(fd_f) : "f"(fs_f[i]) , "f"(ft_f[i]));
87
88#define BINOPd(op) \
89 fd_d = 0; \
90 __asm__ volatile( \
91 op" %0, %1, %2\n\t" \
92 : "=f"(fd_d) : "f"(fs_d[i]) , "f"(ft_d[i]));
93
dejanj34ff1742013-12-05 14:05:25 +000094void set_rounding_mode(round_mode_t mode)
95{
96 switch(mode) {
97 case TO_NEAREST:
98 __asm__ volatile("cfc1 $t0, $31\n\t"
99 "srl $t0, 2\n\t"
100 "sll $t0, 2\n\t"
101 "ctc1 $t0, $31\n\t");
102 break;
103 case TO_ZERO:
104 __asm__ volatile("cfc1 $t0, $31\n\t"
105 "srl $t0, 2\n\t"
106 "sll $t0, 2\n\t"
107 "addiu $t0, 1\n\t"
108 "ctc1 $t0, $31\n\t");
109 break;
110 case TO_PLUS_INFINITY:
111 __asm__ volatile("cfc1 $t0, $31\n\t"
112 "srl $t0, 2\n\t"
113 "sll $t0, 2\n\t"
114 "addiu $t0, 2\n\t"
115 "ctc1 $t0, $31\n\t");
116 break;
117 case TO_MINUS_INFINITY:
118 __asm__ volatile("cfc1 $t0, $31\n\t"
119 "srl $t0, 2\n\t"
120 "sll $t0, 2\n\t"
121 "addiu $t0, 3\n\t"
122 "ctc1 $t0, $31\n\t");
123 break;
124 }
125}
126
127int arithmeticOperations(flt_art_op_t op)
sewardje584b0e2012-06-07 09:32:40 +0000128{
129 double fd_d = 0;
130 float fd_f = 0;
131 int i = 0;
dejanj34ff1742013-12-05 14:05:25 +0000132 round_mode_t rm;
133 for (rm = TO_NEAREST; rm <= TO_MINUS_INFINITY; rm ++) {
134 set_rounding_mode(rm);
135 printf("rounding mode: %s\n", round_mode_name[rm]);
136 for (i = 0; i < 24; i++)
137 {
138 switch(op) {
139 case ABSS:
140 UNOPff("abs.s");
141 printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
142 break;
143 case ABSD:
144 UNOPdd("abs.d");
145 printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
146 break;
147 case ADDS:
148 BINOPf("add.s");
149 printf("%s %f %f %f\n", flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
150 break;
151 case ADDD:
152 BINOPd("add.d");
153 printf("%s %lf %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
154 break;
155 case DIVS:
156 BINOPf("div.s");
157 printf("%s %f %f %f\n", flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
158 break;
159 case DIVD:
160 BINOPd("div.d");
161 printf("%s %lf %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
162 break;
163 case MULS:
164 BINOPf("mul.s");
165 printf("%s %f %f %f\n", flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
166 break;
167 case MULD:
168 BINOPd("mul.d");
169 printf("%s %lf %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
170 break;
171 case NEGS:
172 UNOPff("neg.s");
173 printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
174 break;
175 case NEGD:
176 UNOPdd("neg.d");
177 printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
178 break;
179 case SQRTS:
180 UNOPff("sqrt.s");
181 printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
182 break;
183 case SQRTD:
184 UNOPdd("sqrt.d");
185 printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
186 break;
187 case SUBS:
188 BINOPf("sub.s");
189 printf("%s %f %f %f\n", flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
190 break;
191 case SUBD:
192 BINOPd("sub.d");
193 printf("%s %lf %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
194 break;
195 case RECIPS:
petarj4931c0d2012-07-16 14:07:47 +0000196#if (__mips==32) && (__mips_isa_rev>=2)
dejanj34ff1742013-12-05 14:05:25 +0000197 UNOPff("recip.s");
198 printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
petarj4931c0d2012-07-16 14:07:47 +0000199#endif
dejanj34ff1742013-12-05 14:05:25 +0000200 break;
201 case RECIPD:
petarj4931c0d2012-07-16 14:07:47 +0000202#if (__mips==32) && (__mips_isa_rev>=2)
dejanj34ff1742013-12-05 14:05:25 +0000203 UNOPdd("recip.d");
204 printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
petarj4931c0d2012-07-16 14:07:47 +0000205#endif
dejanj34ff1742013-12-05 14:05:25 +0000206 break;
207 case RSQRTS:
petarj4931c0d2012-07-16 14:07:47 +0000208#if (__mips==32) && (__mips_isa_rev>=2)
dejanj34ff1742013-12-05 14:05:25 +0000209 UNOPff("rsqrt.s");
210 printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
petarj4931c0d2012-07-16 14:07:47 +0000211#endif
dejanj34ff1742013-12-05 14:05:25 +0000212 break;
213 case RSQRTD:
petarj4931c0d2012-07-16 14:07:47 +0000214#if (__mips==32) && (__mips_isa_rev>=2)
dejanj34ff1742013-12-05 14:05:25 +0000215 UNOPdd("rsqrt.d");
216 printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
petarj4931c0d2012-07-16 14:07:47 +0000217#endif
dejanj34ff1742013-12-05 14:05:25 +0000218 break;
219 default:
220 printf("error\n");
221 break;
222 }
223 }
sewardje584b0e2012-06-07 09:32:40 +0000224 }
225 return 0;
226}
227
228int main()
229{
230 flt_art_op_t op;
231
232 printf("-------------------------- %s --------------------------\n",
233 "test FPU Arithmetic Operations");
234 for (op = ABSS; op <= RECIPD; op++) {
235 arithmeticOperations(op);
236 }
237
238 return 0;
239}
Elliott Hughesa0664b92017-04-18 17:46:52 -0700240#else
241int main() {
242 return 0;
243}
244#endif