1#include <stdio.h>
2#include "const.h"
3
4const float reg_val_f[] = {
5   -347856.475, 356047.56,   -1.0,       23.04,
6   1752,        0.0024575,   0.00000001, -248562.76,
7   1384.6,      -7.2945676,  1000000000, -5786.47,
8   -347856.475, 356047.56,   -1.0,       23.04,
9   0,           456.2489562, 3,          -1,
10   -45786.476,  456.2489562, 34.00046,   45786.476,
11   0,           456.2489562, 3,          -1,
12   1384.6,      -7.2945676,  1000000000, -5786.47,
13   1752,        0.0024575,   0.00000001, -248562.76,
14   -45786.476,  456.2489562, 34.00046,   45786.476,
15   1752065,     107,         -45667.24,  -7.2945676,
16   -347856.475, 356047.56,   -1.0,       23.04,
17   -347856.475, 356047.56,   -1.0,       23.04,
18   1752,        0.0024575,   0.00000001, -248562.76,
19   1384.6,      -7.2945676,  1000000000, -5786.47,
20   -347856.475, 356047.56,   -1.0,       23.04,
21   0,           456.2489562, 3,          -1,
22   -45786.476,  456.2489562, 34.00046,   45786.476,
23   0,           456.2489562, 3,          -1,
24   1384.6,      -7.2945676,  1000000000, -5786.47,
25   1752,        0.0024575,   0.00000001, -248562.76,
26   -45786.476,  456.2489562, 34.00046,   45786.476,
27   1752065,     107,         -45667.24,  -7.2945676,
28   -347856.475, 356047.56,   -1.0,       23.04
29};
30
31const float fs1_f[] = {
32   0,           456.2489562, 3,          -1,
33   1384.6,      -7.2945676,  1000000000, -5786.47,
34   1752,        0.0024575,   0.00000001, -248562.76,
35   -45786.476,  456.2489562, 34.00046,   45786.476,
36   1752065,     107,         -45667.24,  -7.2945676,
37   -347856.475, 356047.56,   -1.0,       23.04
38};
39
40const double fs2_f[] = {
41   0,           456.2489562, 3,           -1,
42   -7.2945676,  1384.6,      1000000000,  -5786.47,
43   1752,        0.0024575,   -248562.76,  0.00000001,
44   -45786.476,  45786.476,   456.2489562, 34.00046,
45   1752065,     107,         -45667.24,   -7.2945676,
46   -347856.475, 23.04        -1.0,        356047.56
47};
48
49#define TEST1(mem)                                           \
50{                                                            \
51   unsigned long long out;                                   \
52   __asm__ __volatile__(                                     \
53      ".set  noreorder"  "\n\t"                              \
54      ".set  nomacro"    "\n\t"                              \
55      "move  $t0, %1"    "\n\t"                              \
56      "mtc1  $t0, $f0"   "\n\t"                              \
57      "mov.s $f1, $f0"   "\n\t"                              \
58      "mfc1  $t1, $f1"   "\n\t"                              \
59      "move  %0,  $t1"   "\n\t"                              \
60      ".set  reorder"    "\n\t"                              \
61      ".set  macro"      "\n\t"                              \
62      : "=r" (out)                                           \
63      : "r" (mem)                                            \
64      : "t0", "t1", "$f0", "$f1"                             \
65   );                                                        \
66   printf("mtc1, mov.s, mfc1 :: mem: 0x%llx out: 0x%llx\n",  \
67          (long long)mem, out);                              \
68}
69
70#define TEST2(mem)                                             \
71{                                                              \
72   unsigned long long out;                                     \
73   __asm__ __volatile__(                                       \
74      ".set  noreorder"  "\n\t"                                \
75      ".set  nomacro"    "\n\t"                                \
76      "move  $t0, %1"    "\n\t"                                \
77      "dmtc1 $t0, $f2"   "\n\t"                                \
78      "mov.d $f0, $f2"   "\n\t"                                \
79      "dmfc1 $t1, $f0"   "\n\t"                                \
80      "move  %0,  $t1"   "\n\t"                                \
81      ".set  reorder"  "\n\t"                                  \
82      ".set  macro"    "\n\t"                                  \
83      : "=r" (out)                                             \
84      : "r" (mem)                                              \
85      : "t0", "t1", "$f0", "$f2"                               \
86   );                                                          \
87   printf("dmtc1, mov.d, dmfc1 :: mem: 0x%llx out: 0x%llx\n",  \
88          (long long)mem, out);                                \
89}
90
91/* movX.s fd, fs */
92#define TEST3(instruction, FD, FS, cc, offset)    \
93{                                                 \
94   unsigned int out;                              \
95   __asm__ __volatile__(                          \
96      "li     $t0,    1"               "\n\t"     \
97      "move   $t1,    %1"              "\n\t"     \
98      "mtc1   $t0,    $f0"             "\n\t"     \
99      "mtc1   $t1,    $f2"             "\n\t"     \
100      "dmtc1  $zero,  $"#FD            "\n\t"     \
101      "dmtc1  $zero,  $"#FS            "\n\t"     \
102      "c.eq.s $f0,    $f2"             "\n\t"     \
103      "move   $t0,    %2"              "\n\t"     \
104      "lwc1   $"#FS", "#offset"($t0)"  "\n\t"     \
105      instruction                      "\n\t"     \
106      "mfc1   %0,     $"#FD            "\n\t"     \
107      : "=r" (out)                                \
108      : "r" (cc), "r" (reg_val_f)                 \
109      : "t0", "t1", "$"#FD, "$"#FS, "$f0", "$f2"  \
110   );                                             \
111   printf("%s :: out: 0x%x, cc: %d\n",            \
112          instruction, out, cc);                  \
113}
114
115/* movX.d fd, fs */
116#define TEST3d(instruction, FD, FS, cc, offset)   \
117{                                                 \
118   unsigned long long out;                        \
119   __asm__ __volatile__(                          \
120      "li     $t0,    1"               "\n\t"     \
121      "move   $t1,    %1"              "\n\t"     \
122      "mtc1   $t0,    $f0"             "\n\t"     \
123      "mtc1   $t1,    $f2"             "\n\t"     \
124      "dmtc1  $zero,  $"#FD            "\n\t"     \
125      "c.eq.s $f0,    $f2"             "\n\t"     \
126      "move   $t0,    %2"              "\n\t"     \
127      "ldc1   $"#FS", "#offset"($t0)"  "\n\t"     \
128      instruction                      "\n\t"     \
129      "dmfc1  %0,     $"#FD            "\n\t"     \
130      : "=r" (out)                                \
131      : "r" (cc), "r" (reg_val_f)                 \
132      : "t0", "t1", "$"#FD, "$"#FS, "$f0", "$f2"  \
133   );                                             \
134   printf("%s :: out: 0x%llx, cc: %d\n",          \
135          instruction, out, cc);                  \
136}
137
138/* movX.s fd, fs, rt */
139#define TEST4(instruction, offset, RTval, FD, FS, RT)  \
140{                                                      \
141   unsigned int out;                                   \
142   __asm__ __volatile__(                               \
143      "move  $"#RT", %2"              "\n\t"           \
144      "dmtc1 $zero,  $"#FD            "\n\t"           \
145      "dmtc1 $zero,  $"#FS            "\n\t"           \
146      "move  $t0,    %1"              "\n\t"           \
147      "lwc1  $"#FS", "#offset"($t0)"  "\n\t"           \
148      instruction                     "\n\t"           \
149      "mfc1 %0,     $"#FD"\n\t"                        \
150      : "=r" (out)                                     \
151      : "r" (reg_val_f), "r" (RTval)                   \
152      : "t0", #RT, "$"#FD, "$"#FS                      \
153   );                                                  \
154   printf("%s :: out: 0x%x\n", instruction, out);      \
155}
156
157/* movX.d fd, fs, rt */
158#define TEST4d(instruction, offset, RTval, FD, FS, RT)  \
159{                                                       \
160   unsigned long long out;                              \
161   __asm__ __volatile__(                                \
162      "move  $"#RT", %2"              "\n\t"            \
163      "dmtc1 $zero,  $"#FD            "\n\t"            \
164      "dmtc1 $zero,  $"#FS            "\n\t"            \
165      "move  $t0,    %1"              "\n\t"            \
166      "ldc1  $"#FS", "#offset"($t0)"  "\n\t"            \
167      instruction                     "\n\t"            \
168      "dmfc1 %0,     $"#FD            "\n\t"            \
169      : "=r" (out)                                      \
170      : "r" (reg_val_f), "r" (RTval)                    \
171      : #RT, "t0", "$"#FD, "$"#FS                       \
172   );                                                   \
173   printf("%s :: out: 0x%llx\n", instruction, out);     \
174}
175
176/* movf, movt */
177#define TEST5(instruction, RDval, RSval, RD, RS)                  \
178{                                                                 \
179   unsigned long out;                                             \
180   __asm__ __volatile__(                                          \
181      "c.eq.s      %3,     %4"             "\n\t"                 \
182      "move        $"#RD", %1"             "\n\t"                 \
183      "move        $"#RS", %2"             "\n\t"                 \
184      instruction" $"#RD", $"#RS", $fcc0"  "\n\t"                 \
185      "move        %0,     $"#RD           "\n\t"                 \
186      : "=r" (out)                                                \
187      : "r" (RDval), "r" (RSval), "f" (fs1_f[i]), "f" (fs2_f[i])  \
188      : #RD, #RS                                                  \
189   );                                                             \
190   printf("%s ::  RDval: 0x%x, RSval: 0x%x, out: 0x%lx\n",        \
191          instruction, RDval, RSval, out);                        \
192}
193
194int main()
195{
196   int i;
197   init_reg_val2();
198
199   for (i = 0; i < N; i++) {
200      TEST1(reg_val1[i]);
201      TEST2(reg_val1[i]);
202      TEST1(reg_val2[i]);
203      TEST2(reg_val2[i]);
204   }
205
206   printf("--- MOVF.S ---\n");
207   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 1, 0);
208   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 1, 8);
209   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 1, 16);
210   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 1, 24);
211   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 1, 32)
212   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 1, 40)
213   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 1, 48)
214   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 1, 56)
215   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 0, 0);
216   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 0, 8);
217   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 0, 16);
218   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 0, 24);
219   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 0, 32);
220   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 0, 40);
221   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 0, 48);
222   TEST3("movf.s  $f4, $f6, $fcc0", f4, f6, 0, 56);
223
224   printf("--- MOVF.D ---\n");
225   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 1, 0);
226   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 1, 8);
227   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 1, 16);
228   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 1, 24);
229   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 1, 32);
230   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 1, 40)
231   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 1, 48)
232   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 1, 56)
233   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 0, 0);
234   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 0, 8);
235   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 0, 16);
236   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 0, 24);
237   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 0, 32);
238   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 0, 40);
239   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 0, 48);
240   TEST3d("movf.d  $f4, $f6, $fcc0", f4, f6, 0, 56);
241
242   printf("--- MOVN.S ---\n");
243   TEST4("movn.s  $f0, $f2, $11", 0,  0,          f0, f2, 11);
244   TEST4("movn.s  $f0, $f2, $11", 0,  1,          f0, f2, 11);
245   TEST4("movn.s  $f0, $f2, $11", 8,  0xffff,     f0, f2, 11);
246   TEST4("movn.s  $f0, $f2, $11", 16, -1,         f0, f2, 11);
247   TEST4("movn.s  $f0, $f2, $11", 16, 5,          f0, f2, 11);
248   TEST4("movn.s  $f0, $f2, $11", 24, 0,          f0, f2, 11);
249   TEST4("movn.s  $f0, $f2, $11", 24, 0,          f0, f2, 11);
250   TEST4("movn.s  $f0, $f2, $11", 32, 5,          f0, f2, 11);
251   TEST4("movn.s  $f0, $f2, $11", 32, 125487,     f0, f2, 11);
252   TEST4("movn.s  $f0, $f2, $11", 40, 68,         f0, f2, 11);
253   TEST4("movn.s  $f0, $f2, $11", 40, -122544,    f0, f2, 11);
254   TEST4("movn.s  $f0, $f2, $11", 48, 0,          f0, f2, 11);
255   TEST4("movn.s  $f0, $f2, $11", 48, 0,          f0, f2, 11);
256   TEST4("movn.s  $f0, $f2, $11", 56, 0xffffffff, f0, f2, 11);
257   TEST4("movn.s  $f0, $f2, $11", 56, 0x80000000, f0, f2, 11);
258   TEST4("movn.s  $f0, $f2, $11", 64, 0x7fffffff, f0, f2, 11);
259
260   printf("--- MOVN.D ---\n");
261   TEST4d("movn.d $f0, $f2, $11", 0,  0,          f0, f2, 11);
262   TEST4d("movn.d $f0, $f2, $11", 0,  1,          f0, f2, 11);
263   TEST4d("movn.d $f0, $f2, $11", 8,  0xffff,     f0, f2, 11);
264   TEST4d("movn.d $f0, $f2, $11", 8,  -1,         f0, f2, 11);
265   TEST4d("movn.d $f0, $f2, $11", 16, 5,          f0, f2, 11);
266   TEST4d("movn.d $f0, $f2, $11", 24, 0,          f0, f2, 11);
267   TEST4d("movn.d $f0, $f2, $11", 24, 0,          f0, f2, 11);
268   TEST4d("movn.d $f0, $f2, $11", 32, 5,          f0, f2, 11);
269   TEST4d("movn.d $f0, $f2, $11", 32, 125487,     f0, f2, 11);
270   TEST4d("movn.d $f0, $f2, $11", 40, 68,         f0, f2, 11);
271   TEST4d("movn.d $f0, $f2, $11", 40, -122544,    f0, f2, 11);
272   TEST4d("movn.d $f0, $f2, $11", 48, 0,          f0, f2, 11);
273   TEST4d("movn.d $f0, $f2, $11", 48, 0,          f0, f2, 11);
274   TEST4d("movn.d $f0, $f2, $11", 56, 0xffffffff, f0, f2, 11);
275   TEST4d("movn.d $f0, $f2, $11", 56, 0x80000000, f0, f2, 11);
276   TEST4d("movn.d $f0, $f2, $11", 64, 0x7fffffff, f0, f2, 11);
277
278   printf("--- MOVT.S ---\n");
279   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 0);
280   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 0);
281   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 8);
282   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 16);
283   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 24);
284   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 32);
285   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 40)
286   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 48)
287   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 1, 56)
288   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 0, 0);
289   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 0, 8);
290   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 0, 16);
291   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 0, 24);
292   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 0, 32);
293   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 0, 40);
294   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 0, 48);
295   TEST3("movt.s  $f4, $f6, $fcc0", f4, f6, 0, 56);
296
297   printf("--- MOVT.D ---\n");
298   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 0);
299   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 0);
300   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 8);
301   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 16);
302   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 24);
303   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 32);
304   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 40)
305   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 48)
306   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 1, 56)
307   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 0, 0);
308   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 0, 8);
309   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 0, 16);
310   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 0, 24);
311   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 0, 32);
312   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 0, 40);
313   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 0, 48);
314   TEST3d("movt.d  $f4, $f6, $fcc0", f4, f6, 0, 56);
315
316   printf("--- MOVZ.S ---\n");
317   TEST4("movz.s $f0, $f2, $11", 0,  0,          f0, f2, 11);
318   TEST4("movz.s $f0, $f2, $11", 8,  1,          f0, f2, 11);
319   TEST4("movz.s $f0, $f2, $11", 8,  0xffff,     f0, f2, 11);
320   TEST4("movz.s $f0, $f2, $11", 16, -1,         f0, f2, 11);
321   TEST4("movz.s $f0, $f2, $11", 16, 5,          f0, f2, 11);
322   TEST4("movz.s $f0, $f2, $11", 24, 0,          f0, f2, 11);
323   TEST4("movz.s $f0, $f2, $11", 24, 0,          f0, f2, 11);
324   TEST4("movz.s $f0, $f2, $11", 32, 5,          f0, f2, 11);
325   TEST4("movz.s $f0, $f2, $11", 32, 125487,     f0, f2, 11);
326   TEST4("movz.s $f0, $f2, $11", 40, 68,         f0, f2, 11);
327   TEST4("movz.s $f0, $f2, $11", 40, -122544,    f0, f2, 11);
328   TEST4("movz.s $f0, $f2, $11", 48, 0,          f0, f2, 11);
329   TEST4("movz.s $f0, $f2, $11", 48, 0,          f0, f2, 11);
330   TEST4("movz.s $f0, $f2, $11", 56, 0xffffffff, f0, f2, 11);
331   TEST4("movz.s $f0, $f2, $11", 56, 0x80000000, f0, f2, 11);
332   TEST4("movz.s $f0, $f2, $11", 64, 0x7fffffff, f0, f2, 11);
333
334   printf("--- MOVZ.D ---\n");
335   TEST4d("movz.d $f0, $f2, $11", 0,  0,          f0, f2, 11);
336   TEST4d("movz.d $f0, $f2, $11", 0,  1,          f0, f2, 11);
337   TEST4d("movz.d $f0, $f2, $11", 8,  0xffff,     f0, f2, 11);
338   TEST4d("movz.d $f0, $f2, $11", 16, -1,         f0, f2, 11);
339   TEST4d("movz.d $f0, $f2, $11", 16, 5,          f0, f2, 11);
340   TEST4d("movz.d $f0, $f2, $11", 24, 0,          f0, f2, 11);
341   TEST4d("movz.d $f0, $f2, $11", 24, 0,          f0, f2, 11);
342   TEST4d("movz.d $f0, $f2, $11", 32, 5,          f0, f2, 11);
343   TEST4d("movz.d $f0, $f2, $11", 32, 125487,     f0, f2, 11);
344   TEST4d("movz.d $f0, $f2, $11", 40, 68,         f0, f2, 11);
345   TEST4d("movz.d $f0, $f2, $11", 40, -122544,    f0, f2, 11);
346   TEST4d("movz.d $f0, $f2, $11", 48, 0,          f0, f2, 11);
347   TEST4d("movz.d $f0, $f2, $11", 48, 0,          f0, f2, 11);
348   TEST4d("movz.d $f0, $f2, $11", 56, 0xffffffff, f0, f2, 11);
349   TEST4d("movz.d $f0, $f2, $11", 56, 0x80000000, f0, f2, 11);
350   TEST4d("movz.d $f0, $f2, $11", 64, 0x7fffffff, f0, f2, 11);
351
352   printf("--- MOVF --- if FPConditionalCode(cc) == 0 then "
353          "out = RSval else out = RDval\n");
354   for (i = 0; i < 24; i++) {
355      TEST5("movf", 0xaaaaaaaa, 0x80000000, t0, t1);
356      TEST5("movf", 0xccccffff, 0xffffffff, t1, t2);
357      TEST5("movf", 0xffffaaaa, 0xaaaaffff, t3, t1);
358      TEST5("movf", 0x0,        0xffffffff, t3, t0);
359   }
360
361   printf("--- MOVT --- if FPConditionalCode(cc) == 1 then "
362          "out = RSval else out = RDval\n");
363   for (i = 0; i < 24; i++) {
364      TEST5("movt", 0x0,        0xffffffff, t0, t1);
365      TEST5("movt", 0x11111111, 0xeeeeffff, t1, t2);
366      TEST5("movt", 0x5555ffff, 0xffffffff, t3, t1);
367      TEST5("movt", 0xeeeeeeee, 0xffffeeee, t3, t0);
368   }
369
370   return 0;
371}
372