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