• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 typedef enum {
5    ABSS=0, ABSD,
6    ADDS, ADDD,
7    DIVS, DIVD,
8    MULS, MULD,
9    NEGS, NEGD,
10    SQRTS, SQRTD,
11    SUBS, SUBD,
12    RECIPS, RECIPD,
13    RSQRTS, RSQRTD
14 } flt_art_op_t;
15 
16 const char *flt_art_op_names[] = {
17    "abs.s", "abs.d",
18    "add.s", "add.d",
19    "div.s", "div.d",
20    "mul.s", "mul.d",
21    "neg.s", "neg.d",
22    "sqrt.s", "sqrt.d",
23    "sub.s", "sub.d",
24    "recip.s", "recip.d",
25    "rsqrt.s", "rsqrt.d"
26 };
27 
28 typedef enum {
29    TO_NEAREST=0, TO_ZERO, TO_PLUS_INFINITY, TO_MINUS_INFINITY } round_mode_t;
30 char *round_mode_name[] = { "near", "zero", "+inf", "-inf" };
31 
32 const double fs_d[] = {
33    0,         456.25,   3,          -1,
34    1384.5,    -7.25,    1000000000, -5786.5,
35    1752,      0.015625, 0.03125,    -248562.75,
36    456,       -45786.5, 34.03125,   45786.75,
37    1752065,   107,      -45667.25,  -7,
38    -347856.5, 356047.5, -1.0,       23.0625
39 };
40 
41 const double ft_d[] = {
42    -456.25,    -45786.5, 34.03125,   45786.75,
43    1752065,   107,      -45667.25,  -7.25,
44    -347856.5, 356047.5, -1.0,       23.0625,
45    0,         456.25,   3,          -1,
46    1384.5,    -7,       1000000000, -5786.5,
47    1752,      0.015625, 0.03125,    -248562.75
48 };
49 
50 const float fs_f[] = {
51    0,         456.25,   3,          -1,
52    1384.5,    -7.25,    1000000000, -5786.5,
53    1752,      0.015625, 0.03125,    -248562.75,
54    456,       -45786.5, 34.03125,   45786.75,
55    1752065,   107,      -45667.25,  -7,
56    -347856.5, 356047.5, -1.0,       23.0625
57 };
58 
59 const float ft_f[] = {
60    -456.25,  -4578.5,   34.03125, 4578.75,
61    175,     107,      -456.25,  -7.25,
62    -3478.5, 356.5,    -1.0,     23.0625,
63    0,       456.25,   3,        -1,
64    1384.5,  -7,       100,      -5786.5,
65    1752,    0.015625, 0.03125,  -248562.75
66 };
67 
68 #define UNOPdd(op) \
69         fd_d = 0;  \
70         __asm__ volatile( \
71 					op" %0, %1\n\t" \
72 					: "=f"(fd_d) : "f"(fs_d[i]));
73 
74 #define UNOPff(op) \
75         fd_f = 0;  \
76         __asm__ volatile( \
77 					op" %0, %1\n\t" \
78 					: "=f"(fd_f) : "f"(fs_f[i]));
79 
80 #define BINOPf(op) \
81         fd_f = 0;  \
82         __asm__ volatile( \
83 					op" %0, %1, %2\n\t" \
84 					: "=f"(fd_f) : "f"(fs_f[i]) , "f"(ft_f[i]));
85 
86 #define BINOPd(op) \
87         fd_d = 0;  \
88         __asm__ volatile( \
89 					op" %0, %1, %2\n\t" \
90 					: "=f"(fd_d) : "f"(fs_d[i]) , "f"(ft_d[i]));
91 
set_rounding_mode(round_mode_t mode)92 void set_rounding_mode(round_mode_t mode)
93 {
94    switch(mode) {
95       case TO_NEAREST:
96          __asm__ volatile("cfc1 $t0, $31\n\t"
97                           "srl $t0, 2\n\t"
98                           "sll $t0, 2\n\t"
99                           "ctc1 $t0, $31\n\t");
100          break;
101       case TO_ZERO:
102          __asm__ volatile("cfc1 $t0, $31\n\t"
103                           "srl $t0, 2\n\t"
104                           "sll $t0, 2\n\t"
105                           "addiu $t0, 1\n\t"
106                           "ctc1 $t0, $31\n\t");
107          break;
108       case TO_PLUS_INFINITY:
109          __asm__ volatile("cfc1 $t0, $31\n\t"
110                           "srl $t0, 2\n\t"
111                           "sll $t0, 2\n\t"
112                           "addiu $t0, 2\n\t"
113                           "ctc1 $t0, $31\n\t");
114          break;
115       case TO_MINUS_INFINITY:
116          __asm__ volatile("cfc1 $t0, $31\n\t"
117                           "srl $t0, 2\n\t"
118                           "sll $t0, 2\n\t"
119                           "addiu $t0, 3\n\t"
120                           "ctc1 $t0, $31\n\t");
121          break;
122    }
123 }
124 
arithmeticOperations(flt_art_op_t op)125 int arithmeticOperations(flt_art_op_t op)
126 {
127    double fd_d = 0;
128    float fd_f = 0;
129    int i = 0;
130    round_mode_t rm;
131    for (rm = TO_NEAREST; rm <= TO_MINUS_INFINITY; rm ++) {
132       set_rounding_mode(rm);
133       printf("rounding mode: %s\n", round_mode_name[rm]);
134       for (i = 0; i < 24; i++)
135       {
136          switch(op) {
137             case ABSS:
138                  UNOPff("abs.s");
139                  printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
140                  break;
141             case ABSD:
142                  UNOPdd("abs.d");
143                  printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
144                  break;
145             case ADDS:
146                  BINOPf("add.s");
147                  printf("%s %f %f %f\n", flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
148                  break;
149             case ADDD:
150                  BINOPd("add.d");
151                  printf("%s %lf %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
152                  break;
153             case DIVS:
154                  BINOPf("div.s");
155                  printf("%s %f %f %f\n", flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
156                  break;
157             case DIVD:
158                  BINOPd("div.d");
159                  printf("%s %lf %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
160                  break;
161             case MULS:
162                  BINOPf("mul.s");
163                  printf("%s %f %f %f\n", flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
164                  break;
165             case MULD:
166                  BINOPd("mul.d");
167                  printf("%s %lf %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
168                  break;
169             case NEGS:
170                  UNOPff("neg.s");
171                  printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
172                  break;
173             case NEGD:
174                  UNOPdd("neg.d");
175                  printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
176                  break;
177             case SQRTS:
178                  UNOPff("sqrt.s");
179                  printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
180                  break;
181             case SQRTD:
182                  UNOPdd("sqrt.d");
183                  printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
184                  break;
185             case SUBS:
186                  BINOPf("sub.s");
187                  printf("%s %f %f %f\n", flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
188                  break;
189             case SUBD:
190                  BINOPd("sub.d");
191                  printf("%s %lf %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
192                  break;
193             case RECIPS:
194 #if (__mips==32) && (__mips_isa_rev>=2)
195                  UNOPff("recip.s");
196                  printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
197 #endif
198                  break;
199             case RECIPD:
200 #if (__mips==32) && (__mips_isa_rev>=2)
201                  UNOPdd("recip.d");
202                  printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
203 #endif
204                  break;
205             case RSQRTS:
206 #if (__mips==32) && (__mips_isa_rev>=2)
207                  UNOPff("rsqrt.s");
208                  printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
209 #endif
210                  break;
211             case RSQRTD:
212 #if (__mips==32) && (__mips_isa_rev>=2)
213                  UNOPdd("rsqrt.d");
214                  printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
215 #endif
216                  break;
217             default:
218                printf("error\n");
219                break;
220          }
221       }
222    }
223    return 0;
224 }
225 
main()226 int main()
227 {
228    flt_art_op_t op;
229 
230    printf("-------------------------- %s --------------------------\n",
231         "test FPU Arithmetic Operations");
232    for (op = ABSS; op <= RECIPD; op++) {
233       arithmeticOperations(op);
234    }
235 
236    return 0;
237 }
238 
239