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