1#include <stdio.h>
2
3unsigned int mem[] = {
4   0x4095A266, 0x66666666,
5   0xBFF00000, 0x00000000,
6   0x3FF00000, 0x00000000,
7   0x252a2e2b, 0x262d2d2a,
8   0xFFFFFFFF, 0xFFFFFFFF,
9   0x41D26580, 0xB487E5C9,
10   0x42026580, 0xB750E388,
11   0x3E45798E, 0xE2308C3A,
12   0x3FBF9ADD, 0x3746F65F
13};
14
15float fs_f[] = {
16   0, 456.2489562, 3, -1,
17   1384.6, -7.2945676, 1000000000, -5786.47,
18   1752, 0.0024575, 0.00000001, -248562.76,
19   -45786.476, 456.2489562, 34.00046, 45786.476,
20   1752065, 107, -45667.24, -7.2945676,
21   -347856.475, 356047.56, -1.0, 23.04
22};
23
24double fs_d[] = {
25   0, 456.2489562, 3, -1,
26   1384.6, -7.2945676, 1000000000, -5786.47,
27   1752, 0.0024575, 0.00000001, -248562.76,
28   -45786.476, 456.2489562, 34.00046, 45786.476,
29   1752065, 107, -45667.24, -7.2945676,
30   -347856.475, 356047.56, -1.0, 23.04
31};
32
33double mem1[] = {
34   0, 0, 0, 0,
35   0, 0, 0, 0,
36   0, 0, 0, 0,
37   0, 0, 0, 0
38};
39
40float mem1f[] = {
41   0, 0, 0, 0,
42   0, 0, 0, 0,
43   0, 0, 0, 0,
44   0, 0, 0, 0
45};
46
47// ldc1 $f0, 0($t1)
48#if (__mips_fpr==64)
49#define TESTINSN5LOAD(instruction, RTval, offset, RT) \
50{ \
51    double out; \
52    int out1; \
53    int out2; \
54   __asm__ volatile( \
55     "move $t1, %3\n\t" \
56     "li $t0, " #RTval"\n\t" \
57     instruction "\n\t" \
58     "mov.d %0, $" #RT "\n\t" \
59     "mfc1 %1, $" #RT "\n\t" \
60     "mfhc1 %2, $" #RT "\n\t" \
61     : "=&f" (out), "=&r" (out1), "=&r" (out2) \
62     : "r" (mem), "r" (RTval) \
63     : "cc", "memory" \
64     ); \
65   printf("%s :: ft 0x%x%x\n", \
66          instruction, out1, out2); \
67}
68#else
69#define TESTINSN5LOAD(instruction, RTval, offset, RT) \
70{ \
71    double out; \
72    int out1; \
73    int out2; \
74   __asm__ volatile( \
75     "move $t1, %3\n\t" \
76     "li $t0, " #RTval"\n\t" \
77     instruction "\n\t" \
78     "mov.d %0, $" #RT "\n\t" \
79     "mfc1 %1, $" #RT "\n\t" \
80     "mfc1 %2, $f1\n\t" \
81     : "=&f" (out), "=&r" (out1), "=&r" (out2) \
82     : "r" (mem), "r" (RTval) \
83     : "cc", "memory" \
84     ); \
85   printf("%s :: ft 0x%x%x\n", \
86          instruction, out1, out2); \
87}
88#endif
89
90// lwc1 $f0, 0($t1)
91#define TESTINSN5LOADw(instruction, RTval, offset, RT) \
92{ \
93    double out; \
94    int out1; \
95   __asm__ volatile( \
96     "move $t1, %2\n\t" \
97     "li $t0, " #RTval"\n\t" \
98     instruction "\n\t" \
99     "mov.d %0, $" #RT "\n\t" \
100     "mfc1 %1, $" #RT "\n\t" \
101     : "=&f" (out), "=&r" (out1) \
102     : "r" (mem), "r" (RTval) \
103     : "cc", "memory" \
104     ); \
105   printf("%s :: ft 0x%x\n", \
106          instruction, out1); \
107}
108
109// lwxc1 $f0, $a3($v0)
110#define TESTINSN6LOADw(instruction, indexVal, fd, index, base) \
111{ \
112    int out; \
113   __asm__ volatile( \
114     "move $" #base ", %1\n\t" \
115     "li $" #index ", " #indexVal"\n\t" \
116     instruction "\n\t" \
117     "mfc1 %0, $" #fd "\n\t" \
118     : "=&r" (out) \
119     : "r" (mem) \
120     : "cc", "memory" \
121     ); \
122   printf("%s :: ft 0x%x\n", \
123          instruction, out); \
124}
125
126// ldxc1 $f0, $a3($v0)
127#if (__mips_fpr==64)
128#define TESTINSN6LOADd(instruction, indexVal, fd, index, base) \
129{ \
130    int out1; \
131    int out2; \
132   __asm__ volatile( \
133     "move $" #base ", %2\n\t" \
134     "li $" #index ", " #indexVal"\n\t" \
135     instruction "\n\t" \
136     "mfc1 %0, $" #fd "\n\t" \
137     "mfhc1 %1, $" #fd "\n\t" \
138     : "=&r" (out1), "=&r" (out2) \
139     : "r" (mem) \
140     : "cc", "memory" \
141     ); \
142   printf("%s :: ft lo: 0x%x, ft hi: 0x%x\n", \
143          instruction, out1, out2); \
144}
145#else
146#define TESTINSN6LOADd(instruction, indexVal, fd, index, base) \
147{ \
148    int out1; \
149    int out2; \
150   __asm__ volatile( \
151     "move $" #base ", %2\n\t" \
152     "li $" #index ", " #indexVal"\n\t" \
153     instruction "\n\t" \
154     "mfc1 %0, $" #fd "\n\t" \
155     "mfc1 %1, $f1\n\t" \
156     : "=&r" (out1), "=&r" (out2) \
157     : "r" (mem) \
158     : "cc", "memory" \
159     ); \
160   printf("%s :: ft lo: 0x%x, ft hi: 0x%x\n", \
161          instruction, out1, out2); \
162}
163#endif
164
165// sdc1 $f0, 0($t0)
166#define TESTINST1(offset) \
167{ \
168    unsigned int out; \
169   __asm__ volatile( \
170     "move $t0, %1\n\t" \
171     "move $t1, %2\n\t" \
172     "ldc1 $f0, "#offset"($t1)\n\t" \
173     "sdc1 $f0, "#offset"($t0) \n\t" \
174     "lw %0, "#offset"($t0)\n\t" \
175     : "=&r" (out) \
176     : "r" (mem1), "r" (fs_d) \
177     : "t1", "t0", "cc", "memory" \
178     ); \
179   printf("sdc1 $f0, 0($t0) :: out: 0x%x\n", \
180           out); \
181}
182
183// sdxc1 $f0, $t2($t0)
184#define TESTINST1a(offset) \
185{ \
186    unsigned int out; \
187    unsigned int out1; \
188   __asm__ volatile( \
189     "move $t0, %2\n\t" \
190     "move $t1, %3\n\t" \
191     "li $t2, "#offset"\n\t" \
192     "ldc1 $f0, "#offset"($t1)\n\t" \
193     "sdxc1 $f0, $t2($t0) \n\t" \
194     "lw %0, "#offset"($t0)\n\t" \
195     "addi $t0, $t0, 4 \n\t" \
196     "lw %1, "#offset"($t0)\n\t" \
197     : "=&r" (out), "=&r" (out1) \
198     : "r" (mem1), "r" (fs_d) \
199     : "t2", "t1", "t0", "cc", "memory" \
200     ); \
201   printf("sdc1 $f0, #t2($t0) :: out: 0x%x : out1: 0x%x\n", \
202           out, out1); \
203}
204
205// swc1 $f0, 0($t0)
206#define TESTINST2(offset) \
207{ \
208    unsigned int out; \
209   __asm__ volatile( \
210     "move $t0, %1\n\t" \
211     "move $t1, %2\n\t" \
212     "lwc1 $f0, "#offset"($t1)\n\t" \
213     "swc1 $f0, "#offset"($t0) \n\t" \
214     "lw %0, "#offset"($t0)\n\t" \
215     : "=&r" (out) \
216     : "r" (mem1f), "r" (fs_f) \
217     : "t1", "t0", "cc", "memory" \
218     ); \
219   printf("swc1 $f0, 0($t0) :: out: 0x%x\n", \
220           out); \
221}
222
223// SWXC1 $f0, $t2($t0)
224#define TESTINST2a(offset) \
225{ \
226    unsigned int out; \
227   __asm__ volatile( \
228     "move $t0, %1\n\t" \
229     "move $t1, %2\n\t" \
230     "li $t2, "#offset" \n\t" \
231     "lwc1 $f0, "#offset"($t1)\n\t" \
232     "swxc1 $f0, $t2($t0) \n\t" \
233     "lw %0, "#offset"($t0)\n\t" \
234     : "=&r" (out) \
235     : "r" (mem1f), "r" (fs_f) \
236     : "t2", "t1", "t0", "cc", "memory" \
237     ); \
238   printf("swxc1 $f0, 0($t0) :: out: 0x%x\n", \
239           out); \
240}
241void ppMem(double *m, int len)
242{
243   int i;
244   printf("MEM1:\n");
245   for (i = 0; i < len; i=i+4)
246   {
247      printf("%lf, %lf, %lf, %lf\n", m[i], m[i+1], m[i+2], m[i+3]);
248      m[i] = 0;
249      m[i+1] = 0;
250      m[i+2] = 0;
251      m[i+3] = 0;
252   }
253}
254
255void ppMemF(float *m, int len)
256{
257   int i;
258   printf("MEM1:\n");
259   for (i = 0; i < len; i=i+4)
260   {
261      printf("%lf, %lf, %lf, %lf\n", m[i], m[i+1], m[i+2], m[i+3]);
262      m[i] = 0;
263      m[i+1] = 0;
264      m[i+2] = 0;
265      m[i+3] = 0;
266   }
267}
268
269int main()
270{
271   printf("LDC1\n");
272   TESTINSN5LOAD("ldc1 $f0, 0($t1)", 0, 0, f0);
273   TESTINSN5LOAD("ldc1 $f0, 8($t1)", 0, 8, f0);
274   TESTINSN5LOAD("ldc1 $f0, 16($t1)", 0, 16, f0);
275   TESTINSN5LOAD("ldc1 $f0, 24($t1)", 0, 24, f0);
276   TESTINSN5LOAD("ldc1 $f0, 32($t1)", 0, 32, f0);
277   TESTINSN5LOAD("ldc1 $f0, 40($t1)", 0, 40, f0);
278   TESTINSN5LOAD("ldc1 $f0, 48($t1)", 0, 48, f0);
279   TESTINSN5LOAD("ldc1 $f0, 56($t1)", 0, 56, f0);
280   TESTINSN5LOAD("ldc1 $f0, 64($t1)", 0, 64, f0);
281   TESTINSN5LOAD("ldc1 $f0, 0($t1)", 0, 0, f0);
282   TESTINSN5LOAD("ldc1 $f0, 8($t1)", 0, 8, f0);
283   TESTINSN5LOAD("ldc1 $f0, 16($t1)", 0, 16, f0);
284   TESTINSN5LOAD("ldc1 $f0, 24($t1)", 0, 24, f0);
285   TESTINSN5LOAD("ldc1 $f0, 32($t1)", 0, 32, f0);
286   TESTINSN5LOAD("ldc1 $f0, 40($t1)", 0, 40, f0);
287   TESTINSN5LOAD("ldc1 $f0, 48($t1)", 0, 48, f0);
288   TESTINSN5LOAD("ldc1 $f0, 56($t1)", 0, 56, f0);
289   TESTINSN5LOAD("ldc1 $f0, 0($t1)", 0, 0, f0);
290   TESTINSN5LOAD("ldc1 $f0, 8($t1)", 0, 8, f0);
291   TESTINSN5LOAD("ldc1 $f0, 16($t1)", 0, 16, f0);
292   TESTINSN5LOAD("ldc1 $f0, 24($t1)", 0, 24, f0);
293   TESTINSN5LOAD("ldc1 $f0, 32($t1)", 0, 32, f0);
294   TESTINSN5LOAD("ldc1 $f0, 40($t1)", 0, 40, f0);
295   TESTINSN5LOAD("ldc1 $f0, 48($t1)", 0, 48, f0);
296   TESTINSN5LOAD("ldc1 $f0, 56($t1)", 0, 56, f0);
297   TESTINSN5LOAD("ldc1 $f0, 64($t1)", 0, 64, f0);
298   TESTINSN5LOAD("ldc1 $f0, 0($t1)", 0, 0, f0);
299
300   printf("LWC1\n");
301   TESTINSN5LOADw("lwc1 $f0, 0($t1)", 0, 0, f0);
302   TESTINSN5LOADw("lwc1 $f0, 4($t1)", 0, 4, f0);
303   TESTINSN5LOADw("lwc1 $f0, 8($t1)", 0, 8, f0);
304   TESTINSN5LOADw("lwc1 $f0, 12($t1)", 0, 12, f0);
305   TESTINSN5LOADw("lwc1 $f0, 16($t1)", 0, 16, f0);
306   TESTINSN5LOADw("lwc1 $f0, 20($t1)", 0, 20, f0);
307   TESTINSN5LOADw("lwc1 $f0, 24($t1)", 0, 24, f0);
308   TESTINSN5LOADw("lwc1 $f0, 28($t1)", 0, 28, f0);
309   TESTINSN5LOADw("lwc1 $f0, 32($t1)", 0, 32, f0);
310   TESTINSN5LOADw("lwc1 $f0, 36($t1)", 0, 36, f0);
311   TESTINSN5LOADw("lwc1 $f0, 40($t1)", 0, 40, f0);
312   TESTINSN5LOADw("lwc1 $f0, 44($t1)", 0, 44, f0);
313   TESTINSN5LOADw("lwc1 $f0, 48($t1)", 0, 48, f0);
314   TESTINSN5LOADw("lwc1 $f0, 52($t1)", 0, 52, f0);
315   TESTINSN5LOADw("lwc1 $f0, 56($t1)", 0, 56, f0);
316   TESTINSN5LOADw("lwc1 $f0, 60($t1)", 0, 60, f0);
317   TESTINSN5LOADw("lwc1 $f0, 64($t1)", 0, 64, f0);
318   TESTINSN5LOADw("lwc1 $f0, 0($t1)", 0, 0, f0);
319   TESTINSN5LOADw("lwc1 $f0, 8($t1)", 0, 8, f0);
320   TESTINSN5LOADw("lwc1 $f0, 16($t1)", 0, 16, f0);
321   TESTINSN5LOADw("lwc1 $f0, 24($t1)", 0, 24, f0);
322   TESTINSN5LOADw("lwc1 $f0, 32($t1)", 0, 32, f0);
323   TESTINSN5LOADw("lwc1 $f0, 40($t1)", 0, 40, f0);
324   TESTINSN5LOADw("lwc1 $f0, 48($t1)", 0, 48, f0);
325   TESTINSN5LOADw("lwc1 $f0, 56($t1)", 0, 56, f0);
326   TESTINSN5LOADw("lwc1 $f0, 64($t1)", 0, 64, f0);
327   TESTINSN5LOADw("lwc1 $f0, 0($t1)", 0, 0, f0);
328
329#if (__mips==32) && (__mips_isa_rev>=2)
330   printf("LWXC1\n");
331   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 0, f0, a3, v0);
332   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 4, f0, a3, v0);
333   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 8, f0, a3, v0);
334   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 12, f0, a3, v0);
335   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 16, f0, a3, v0);
336   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 20, f0, a3, v0);
337   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 24, f0, a3, v0);
338   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 28, f0, a3, v0);
339   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 32, f0, a3, v0);
340   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 36, f0, a3, v0);
341   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 40, f0, a3, v0);
342   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 44, f0, a3, v0);
343   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 48, f0, a3, v0);
344   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 52, f0, a3, v0);
345   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 56, f0, a3, v0);
346   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 60, f0, a3, v0);
347   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 64, f0, a3, v0);
348   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 0, f0, a3, v0);
349   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 4, f0, a3, v0);
350   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 8, f0, a3, v0);
351   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 12, f0, a3, v0);
352   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 16, f0, a3, v0);
353   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 20, f0, a3, v0);
354   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 24, f0, a3, v0);
355   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 28, f0, a3, v0);
356   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 32, f0, a3, v0);
357   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 36, f0, a3, v0);
358   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 40, f0, a3, v0);
359   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 44, f0, a3, v0);
360   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 48, f0, a3, v0);
361   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 52, f0, a3, v0);
362   TESTINSN6LOADw("lwxc1 $f0, $a3($v0)", 56, f0, a3, v0);
363
364   printf("LDXC1\n");
365   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 0, f0, a3, v0);
366   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 8, f0, a3, v0);
367   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 16, f0, a3, v0);
368   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 24, f0, a3, v0);
369   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 32, f0, a3, v0);
370   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 40, f0, a3, v0);
371   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 48, f0, a3, v0);
372   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 56, f0, a3, v0);
373   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 64, f0, a3, v0);
374   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 0, f0, a3, v0);
375   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 8, f0, a3, v0);
376   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 16, f0, a3, v0);
377   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 24, f0, a3, v0);
378   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 32, f0, a3, v0);
379   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 40, f0, a3, v0);
380   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 48, f0, a3, v0);
381   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 56, f0, a3, v0);
382   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 64, f0, a3, v0);
383   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 0, f0, a3, v0);
384   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 8, f0, a3, v0);
385   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 16, f0, a3, v0);
386   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 24, f0, a3, v0);
387   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 32, f0, a3, v0);
388   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 40, f0, a3, v0);
389   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 48, f0, a3, v0);
390   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 56, f0, a3, v0);
391   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 64, f0, a3, v0);
392   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 0, f0, a3, v0);
393   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 8, f0, a3, v0);
394   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 16, f0, a3, v0);
395   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 24, f0, a3, v0);
396   TESTINSN6LOADd("ldxc1 $f0, $a3($v0)", 32, f0, a3, v0);
397#endif
398
399   printf("SDC1\n");
400   TESTINST1(0);
401   TESTINST1(8);
402   TESTINST1(16);
403   TESTINST1(24);
404   TESTINST1(32);
405   TESTINST1(40);
406   TESTINST1(48);
407   TESTINST1(56);
408   TESTINST1(64);
409   ppMem(mem1, 16);
410
411#if (__mips==32) && (__mips_isa_rev>=2)
412   printf("SDXC1\n");
413   TESTINST1a(0);
414   TESTINST1a(8);
415   TESTINST1a(16);
416   TESTINST1a(24);
417   TESTINST1a(32);
418   TESTINST1a(40);
419   TESTINST1a(48);
420   TESTINST1a(56);
421   TESTINST1a(64);
422   ppMem(mem1, 16);
423#endif
424
425   printf("SWC1\n");
426   TESTINST2(0);
427   TESTINST2(8);
428   TESTINST2(16);
429   TESTINST2(24);
430   TESTINST2(32);
431   TESTINST2(40);
432   TESTINST2(48);
433   TESTINST2(56);
434   TESTINST2(64);
435   ppMemF(mem1f, 16);
436
437#if (__mips==32) && (__mips_isa_rev>=2)
438   printf("SWXC1\n");
439   TESTINST2a(0);
440   TESTINST2a(8);
441   TESTINST2a(16);
442   TESTINST2a(24);
443   TESTINST2a(32);
444   TESTINST2a(40);
445   TESTINST2a(48);
446   TESTINST2a(56);
447   TESTINST2a(64);
448   ppMemF(mem1f, 16);
449#endif
450
451   return 0;
452}
453
454