1 #include "const.h"
2 
3 typedef enum {
4    ABSS=0, ABSD,   ADDS,   ADDD,
5    DIVS,   DIVD,   MULS,   MULD,
6    NEGS,   NEGD,   SQRTS,  SQRTD,
7    SUBS,   SUBD,   RECIPS, RECIPD,
8    RSQRTS, RSQRTD,
9 #if (__mips_isa_rev < 6)
10    MSUBS,  MSUBD,  MADDS,  MADDD,
11    NMADDS, NMADDD, NMSUBS, NMSUBD
12 #endif
13 } flt_art_op_t;
14 
15 typedef enum {
16    CEILWS=0, CEILWD,  FLOORWS,  FLOORWD,
17    ROUNDWS,  ROUNDWD, TRUNCWS,  TRUNCWD,
18    CEILLS,   CEILLD,  FLOORLS,  FLOORLD,
19    ROUNDLS,  ROUNDLD, TRUNCLS,  TRUNCLD
20 } flt_dir_op_t;
21 
22 typedef enum {
23    CVTDS, CVTDW, CVTSD, CVTSW,
24    CVTWS, CVTWD, CVTDL, CVTLS,
25    CVTLD, CVTSL,
26 } flt_round_op_t;
27 
28 const char *flt_art_op_names[] = {
29    "abs.s",   "abs.d",   "add.s",   "add.d",
30    "div.s",   "div.d",   "mul.s",   "mul.d",
31    "neg.s",   "neg.d",   "sqrt.s",  "sqrt.d",
32    "sub.s",   "sub.d",   "recip.s", "recip.d",
33    "rsqrt.s", "rsqrt.d", "msub.s",  "msub.d",
34    "madd.s",  "madd.d",  "nmadd.s", "nmadd.d",
35    "nmsub.s", "nmsub.d"
36 };
37 
38 const char *flt_dir_op_names[] = {
39    "ceil.w.s",  "ceil.w.d",
40    "floor.w.s", "floor.w.d",
41    "round.w.s", "round.w.d",
42    "trunc.w.s", "trunc.w.d",
43    "ceil.l.s",  "ceil.l.d",
44    "floor.l.s", "floor.l.d",
45    "round.l.s", "round.l.d",
46    "trunc.l.s", "trunc.l.d"
47 };
48 
49 const char *flt_round_op_names[] = {
50    "cvt.d.s", "cvt.d.w",
51    "cvt.s.d", "cvt.s.w",
52    "cvt.w.s", "cvt.w.d",
53    "cvt.d.l", "cvt.l.s",
54    "cvt.l.d", "cvt.s.l",
55 };
56 
57 #if defined(__mips_hard_float)
58 #define UNOPdd(op)               \
59    fd_d = 0;                     \
60    __asm__ __volatile__(         \
61       op"   %1, %2"   "\n\t"     \
62       "cfc1 %0, $31"  "\n\t"     \
63       : "=r" (fcsr), "=f"(fd_d)  \
64       : "f"(fs_d[i])             \
65    );
66 
67 #define UNOPff(op)               \
68    fd_f = 0;                     \
69    __asm__ __volatile__(         \
70       op"   %1, %2"   "\n\t"     \
71       "cfc1 %0, $31"  "\n\t"     \
72       : "=r" (fcsr), "=f"(fd_f)  \
73       : "f"(fs_f[i])             \
74    );
75 
76 #define UNOPfd(op)               \
77    fd_d = 0;                     \
78    __asm__ __volatile__(         \
79       op"   %1, %2"   "\n\t"     \
80       "cfc1 %0, $31"  "\n\t"     \
81       : "=r" (fcsr), "=f"(fd_d)  \
82       : "f"(fs_f[i])             \
83    );
84 
85 #define UNOPdf(op)               \
86    fd_f = 0;                     \
87    __asm__ __volatile__(         \
88       op"   %1, %2"   "\n\t"     \
89       "cfc1 %0, $31"  "\n\t"     \
90       : "=r" (fcsr), "=f"(fd_f)  \
91       : "f"(fs_d[i])             \
92    );
93 
94 #define UNOPfw(op)               \
95    fd_w = 0;                     \
96    __asm__ __volatile__(         \
97       op"   $f0, %2"   "\n\t"    \
98       "mfc1 %1,  $f0"  "\n\t"    \
99       "cfc1 %0,  $31"  "\n\t"    \
100       : "=r" (fcsr), "=r"(fd_w)  \
101       : "f"(fs_f[i])             \
102       : "$f0"                    \
103    );
104 
105 #define UNOPdw(op)               \
106    fd_w = 0;                     \
107    __asm__ __volatile__(         \
108       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"                    \
114    );
115 
116 #define UNOPwd(op)               \
117    fd_d = 0;                     \
118    __asm__ __volatile__(         \
119       "mtc1 %2,  $f0"  "\n\t"    \
120       op"   %1,  $f0"  "\n\t"    \
121       "cfc1 %0,  $31"  "\n\t"    \
122       : "=r" (fcsr), "=f"(fd_d)  \
123       : "r"(fs_w[i])             \
124       : "$f0"                    \
125    );
126 
127 #define UNOPwf(op)               \
128    fd_f = 0;                     \
129    __asm__ __volatile__(         \
130       "mtc1 %2,  $f0"  "\n\t"    \
131       op"   %1,  $f0"  "\n\t"    \
132       "cfc1 %0,  $31"  "\n\t"    \
133       : "=r" (fcsr), "=f"(fd_f)  \
134       : "r"(fs_w[i])             \
135       : "$f0"                    \
136    );
137 
138 #define UNOPld(op)               \
139    fd_d = 0;                     \
140    __asm__ __volatile__(         \
141       "dmtc1 %2, $f0"  "\n\t"    \
142       op"    %1, $f0"  "\n\t"    \
143       "cfc1  %0, $31"  "\n\t"    \
144       : "=r" (fcsr), "=f"(fd_d)  \
145       : "r"(fs_l[i])             \
146       : "$f0"                    \
147    );
148 
149 #define UNOPdl(op)               \
150    fd_l = 0;                     \
151    __asm__ __volatile__(         \
152       op"    $f0, %2"   "\n\t"   \
153       "dmfc1 %1,  $f0"  "\n\t"   \
154       "cfc1  %0,  $31"  "\n\t"   \
155       : "=r" (fcsr), "=r"(fd_l)  \
156       : "f"(fs_d[i])             \
157       : "$f0"                    \
158    );
159 
160 #define UNOPls(op)               \
161    fd_f = 0;                     \
162    __asm__ __volatile__(         \
163       "dmtc1 %2, $f0"  "\n\t"    \
164       op"    %1, $f0"  "\n\t"    \
165       "cfc1  %0, $31"  "\n\t"    \
166       : "=r" (fcsr), "=f"(fd_f)  \
167       : "r"(fs_l[i])             \
168       : "$f0"                    \
169    );
170 
171 #define UNOPsl(op)               \
172    fd_l = 0;                     \
173    __asm__ __volatile__(         \
174       op"    $f0, %2"   "\n\t"   \
175       "dmfc1 %1,  $f0"  "\n\t"   \
176       "cfc1  %0,  $31"  "\n\t"   \
177       : "=r" (fcsr), "=r"(fd_l)  \
178       : "f"(fs_f[i])             \
179       : "$f0"                    \
180    );
181 
182 #define BINOPf(op)                    \
183    fd_f = 0;                          \
184    __asm__ __volatile__(              \
185       op"    %1, %2, %3"  "\n\t"      \
186       "cfc1  %0, $31"     "\n\t"      \
187       : "=r" (fcsr), "=f" (fd_f)      \
188       : "f" (fs_f[i]), "f" (ft_f[i])  \
189    );
190 
191 #define BINOPd(op)                    \
192    fd_d = 0;                          \
193    __asm__ __volatile__(              \
194       op" %1, %2, %3"  "\n\t"         \
195       "cfc1  %0, $31"     "\n\t"      \
196       : "=r" (fcsr), "=f"(fd_d)       \
197       : "f" (fs_d[i]), "f" (ft_d[i])  \
198    );
199 
200 #define TRIOPf(op)                                    \
201    fd_f = 0;                                          \
202    __asm__ __volatile__(                              \
203       op"    %1, %2, %3, %4"  "\n\t"                  \
204       "cfc1  %0, $31"         "\n\t"                  \
205       : "=r" (fcsr), "=f" (fd_f)                      \
206       : "f" (fr_f[i]), "f" (fs_f[i]) , "f" (ft_f[i])  \
207    );
208 
209 #define TRIOPd(op)                                    \
210    fd_d = 0;                                          \
211    __asm__ __volatile__(                              \
212       op"    %1, %2, %3, %4"  "\n\t"                  \
213       "cfc1  %0, $31"         "\n\t"                  \
214       : "=r" (fcsr), "=f"(fd_d)                       \
215       : "f" (fr_d[i]), "f" (fs_d[i]) , "f" (ft_d[i])  \
216    );
217 
218 /* Conditional macros.*/
219 #define TESTINST1s(instruction, RDval)               \
220 {                                                    \
221    float outf = 0;                                   \
222    __asm__ __volatile__(                             \
223       ".set        noreorder"                "\n\t"  \
224       "mov.s       $f1,   %1"                "\n\t"  \
225       "mov.s       $f2,   %2"                "\n\t"  \
226       "mtc1        $zero, $f0"               "\n\t"  \
227       "c.eq.s      $f1,   $f2"               "\n\t"  \
228       instruction" end"instruction"s"#RDval  "\n\t"  \
229       "nop"                                  "\n\t"  \
230       "add.s       $f0,   $f0, $f1"          "\n\t"  \
231       "end"instruction"s"#RDval":"           "\n\t"  \
232       "add.s       $f0,   $f0, $f2"          "\n\t"  \
233       "mov.s       %0,    $f0"               "\n\t"  \
234       ".set        reorder"                  "\n\t"  \
235       : "=f" (outf)                                  \
236       : "f" (fs_f[i]) , "f" (ft_f[i])                \
237       : "$f0", "$f1", "$f2"                          \
238    );                                                \
239    printf("%s, c.eq.s   out=%f, fs=%f, ft=%f\n",     \
240           instruction, outf, fs_f[i], ft_f[i]);      \
241 }
242 
243 #define TESTINST1d(instruction, RDval)               \
244 {                                                    \
245    double outd = 0;                                  \
246    __asm__ __volatile__(                             \
247       ".set        noreorder"                "\n\t"  \
248       "mov.d       $f1,   %1"                "\n\t"  \
249       "mov.d       $f2,   %2"                "\n\t"  \
250       "dmtc1       $zero, $f0"               "\n\t"  \
251       "c.eq.d      $f1,   $f2"               "\n\t"  \
252       instruction" end"instruction"d"#RDval  "\n\t"  \
253       "nop"                                  "\n\t"  \
254       "add.d       $f0,   $f0, $f1"          "\n\t"  \
255       "end"instruction"d"#RDval":"           "\n\t"  \
256       "add.d       $f0,   $f0, $f2"          "\n\t"  \
257       "mov.d       %0,    $f0"               "\n\t"  \
258       ".set        reorder"                  "\n\t"  \
259       : "=f" (outd)                                  \
260       : "f" (fs_d[i]) , "f" (ft_d[i])                \
261       : "$f0", "$f1", "$f2"                          \
262    );                                                \
263    printf("%s, c.eq.d   out=%f, fs=%f, ft=%f\n",     \
264           instruction, outd, fs_d[i], ft_d[i]);      \
265 }
266 
267 #define TESTINST2s(instruction, RDval)               \
268 {                                                    \
269    float outf = 0;                                   \
270    __asm__ __volatile__(                             \
271       ".set        noreorder"                "\n\t"  \
272       "mov.s       $f1,   %1"                "\n\t"  \
273       "mov.s       $f2,   %2"                "\n\t"  \
274       "mtc1        $zero, $f0"               "\n\t"  \
275       "c.eq.s      $f1,   $f2"               "\n\t"  \
276       instruction" end"instruction"s"#RDval  "\n\t"  \
277       "add.s       $f0,   $f0, $f1"          "\n\t"  \
278       "end"instruction"s"#RDval":"           "\n\t"  \
279       "add.s       $f0,   $f0, $f2"          "\n\t"  \
280       "mov.s       %0, $f0"                  "\n\t"  \
281       ".set        reorder"                  "\n\t"  \
282       : "=f" (outf)                                  \
283       : "f" (fs_f[i]) , "f" (ft_f[i])                \
284       : "$f0", "$f1", "$f2"                          \
285    );                                                \
286    printf("%s, c.eq.s   out=%f, fs=%f, ft=%f\n",     \
287           instruction, outf, fs_f[i], ft_f[i]);      \
288 }
289 
290 #define TESTINST2d(instruction, RDval)               \
291 {                                                    \
292    double outd = 0;                                  \
293    __asm__ __volatile__(                             \
294       ".set        noreorder"                "\n\t"  \
295       "mov.d       $f1,   %1"                "\n\t"  \
296       "mov.d       $f2,   %2"                "\n\t"  \
297       "dmtc1       $zero, $f0"               "\n\t"  \
298       "c.eq.d      $f1,   $f2"               "\n\t"  \
299       instruction" end"instruction"d"#RDval  "\n\t"  \
300       "add.d       $f0,   $f0, $f1"          "\n\t"  \
301       "end"instruction"d"#RDval":"           "\n\t"  \
302       "add.d       $f0,   $f0, $f2"          "\n\t"  \
303       "mov.d       %0, $f0"                  "\n\t"  \
304       ".set        reorder"                  "\n\t"  \
305       : "=f" (outd)                                  \
306       : "f" (fs_d[i]) , "f" (ft_d[i])                \
307       : "$f0", "$f1", "$f2"                          \
308    );                                                \
309    printf("%s, c.eq.d   out=%f, fs=%f, ft=%f\n",     \
310           instruction, outd, fs_d[i], ft_d[i]);      \
311 }
312 
313 #define TESTINST_CONDs(instruction, RDval)       \
314 {                                                \
315    float outf = 0;                               \
316    __asm__ __volatile__(                         \
317       ".set        noreorder"         "\n\t"     \
318       "mov.s       $f1,   %1"         "\n\t"     \
319       "mov.s       $f2,   %2"         "\n\t"     \
320       "mov.s       $f0,   %1"         "\n\t"     \
321       instruction" $f1,   $f2"        "\n\t"     \
322       "bc1f end"instruction"s"#RDval  "\n\t"     \
323       "nop"                           "\n\t"     \
324       "add.s       $f0,   $f0, $f2"   "\n\t"     \
325       "end"instruction"s"#RDval":"    "\n\t"     \
326       "mov.s       %0,    $f0"        "\n\t"     \
327       ".set        reorder"           "\n\t"     \
328       : "=f" (outf)                              \
329       : "f" (fs_f[i]) , "f" (ft_f[i])            \
330       : "$f0", "$f1", "$f2"                      \
331    );                                            \
332    printf("%s, bc1f   out=%f, fs=%f, ft=%f\n",   \
333           instruction, outf, fs_f[i], ft_f[i]);  \
334 }
335 
336 #define TESTINST_CONDd(instruction, RDval)       \
337 {                                                \
338    double outd = 0;                              \
339    __asm__ __volatile__(                         \
340       ".set        noreorder"         "\n\t"     \
341       "mov.d       $f1,   %1"         "\n\t"     \
342       "mov.d       $f2,   %2"         "\n\t"     \
343       "mov.d       $f0,   %1"         "\n\t"     \
344       instruction" $f1,   $f2"        "\n\t"     \
345       "bc1f end"instruction"d"#RDval  "\n\t"     \
346       "nop"                           "\n\t"     \
347       "add.d       $f0,   $f0, $f2"   "\n\t"     \
348       "end"instruction"d"#RDval":"    "\n\t"     \
349       "mov.d       %0,    $f0"        "\n\t"     \
350       ".set        reorder"           "\n\t"     \
351       : "=f" (outd)                              \
352       : "f" (fs_d[i]) , "f" (ft_d[i])            \
353       : "$f0", "$f1", "$f2"                      \
354    );                                            \
355    printf("%s, bc1f   out=%f, fs=%f, ft=%f\n",   \
356           instruction, outd, fs_d[i], ft_d[i]);  \
357 }
358 #endif
359