• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #if defined(__mips_hard_float)
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <signal.h>
6 #include <setjmp.h>
7 
8 #define MAX_ARR 24
9 #define PERROR \
10         printf("This test is testing mips32r2 instructions in fpu64 mode.\n");
11 #define FLAGS_RM_MASK 0xFFFFFFFF
12 
13 typedef enum {
14    CVTLS,   CVTLD,   ROUNDLS, ROUNDLD,
15    TRUNCLS, TRUNCLD, FLOORLS, FLOORLD,
16    CEILLS,  CEILLD
17 } flt_round_op_t;
18 
19 const char *flt_round_op_names[] = {
20    "cvt.l.s",   "cvt.l.d",   "round.l.s", "round.l.d",
21    "trunc.l.s", "trunc.l.d", "floor.l.s", "floor.l.d"
22    "ceil.l.s",  "ceil.l.d"
23 };
24 
25 typedef enum {
26    TO_NEAREST=0, TO_ZERO, TO_PLUS_INFINITY, TO_MINUS_INFINITY } round_mode_t;
27 char *round_mode_name[] = { "near", "zero", "+inf", "-inf" };
28 
29 const float fs_f[] = {
30    0,         456.25,   3,          -1,
31    1384.5,    -7.25,    1000000000, -5786.25,
32    1752,      0.015625, 0.03125,    -248562.75,
33    -45786.5,  456,      34.03125,   45786.75,
34    1752065,   107,      -45667.25,  -7,
35    -347856.5, 356047,   -1.25,      23.0625
36 };
37 
38 const double fs_d[] = {
39    0,         456.25,   3,          -1,
40    1384.5,    -7.25,    1000000000, -5786.25,
41    1752,      0.015625, 0.03125,    -24856226678933.75,
42    -45786.5,  456,      34.03125,   45786.75,
43    1752065,   107,      -45667.25,  -7,
44    -347856.5, 356047,   -1.25,      23.0625
45 };
46 
47 #define UNOPsl(op)                \
48    __asm__ __volatile__(          \
49       op"   $f0, %2"     "\n\t"   \
50       "sdc1 $f0, 0(%1)"  "\n\t"   \
51       "cfc1 %0,  $31"    "\n\t"   \
52       : "=r" (fcsr)               \
53       : "r"(&fd_l), "f"(fs_f[i])  \
54       : "$f0"                     \
55    );
56 
57 #define UNOPdl(op)                \
58    __asm__ __volatile__(          \
59       op"   $f0, %2"     "\n\t"   \
60       "sdc1 $f0, 0(%1)"  "\n\t"   \
61       "cfc1 %0,  $31"    "\n\t"   \
62       : "=r" (fcsr)               \
63       : "r"(&fd_l), "f"(fs_d[i])  \
64       : "$f0"                     \
65    );
66 
67 #define TEST_FPU64                \
68    __asm__ __volatile__(          \
69       "cvt.l.s $f0, $f0"  "\n\t"  \
70       :                           \
71       :                           \
72       : "$f0"                     \
73    );
74 
75 #if (__mips==32) && (__mips_isa_rev>=2) && \
76     ((__mips_fpr==64) || (__mips_fpr==xx))
set_rounding_mode(round_mode_t mode)77 void set_rounding_mode(round_mode_t mode)
78 {
79    switch(mode) {
80       case TO_NEAREST:
81          __asm__ volatile("ctc1 $zero, $31"  "\n\t");
82          break;
83       case TO_ZERO:
84          __asm__ volatile("li    $t0, 0x1"  "\n\t"
85                           "ctc1  $t0, $31"  "\n\t");
86          break;
87       case TO_PLUS_INFINITY:
88           __asm__ volatile("li    $t0, 0x2"  "\n\t"
89                            "ctc1  $t0, $31"  "\n\t");
90          break;
91       case TO_MINUS_INFINITY:
92           __asm__ volatile("li    $t0, 0x3"  "\n\t"
93                            "ctc1  $t0, $31"  "\n\t");
94          break;
95    }
96 }
97 
98 struct test {
99    void (*test)(void);
100    int sig;
101    int code;
102 };
103 
handler(int sig)104 static void handler(int sig)
105 {
106    PERROR;
107    exit(0);
108 }
109 
FCSRRoundingMode(flt_round_op_t op)110 int FCSRRoundingMode(flt_round_op_t op)
111 {
112    long long int fd_l;
113    int i;
114    int fcsr = 0;
115    round_mode_t rm;
116    for (rm = TO_NEAREST; rm <= TO_MINUS_INFINITY; rm ++) {
117       printf("roundig mode: %s\n", round_mode_name[rm]);
118       for (i = 0; i < MAX_ARR; i++) {
119          set_rounding_mode(rm);
120          switch(op) {
121             case CVTLS:
122                UNOPsl("cvt.l.s");
123                printf("%s %lld %f\n",
124                       flt_round_op_names[op], fd_l, fs_f[i]);
125                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
126                break;
127             case CVTLD:
128                UNOPdl("cvt.l.d");
129                printf("%s %lld %lf\n",
130                       flt_round_op_names[op], fd_l, fs_d[i]);
131                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
132                break;
133             case ROUNDLS:
134                UNOPsl("round.l.s");
135                printf("%s %lld %f\n",
136                       flt_round_op_names[op], fd_l, fs_f[i]);
137                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
138                break;
139             case ROUNDLD:
140                UNOPdl("round.l.d");
141                printf("%s %lld %lf\n",
142                       flt_round_op_names[op], fd_l, fs_d[i]);
143                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
144                break;
145             case TRUNCLS:
146                UNOPsl("trunc.l.s");
147                printf("%s %lld %f\n",
148                       flt_round_op_names[op], fd_l, fs_f[i]);
149                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
150                break;
151             case TRUNCLD:
152                UNOPdl("trunc.l.d");
153                printf("%s %lld %lf\n",
154                       flt_round_op_names[op], fd_l, fs_d[i]);
155                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
156                break;
157             case FLOORLS:
158                UNOPsl("floor.l.s");
159                printf("%s %lld %f\n",
160                       flt_round_op_names[op], fd_l, fs_f[i]);
161                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
162                break;
163             case FLOORLD:
164                UNOPdl("floor.l.d");
165                printf("%s %lld %lf\n",
166                       flt_round_op_names[op], fd_l, fs_d[i]);
167                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
168                break;
169             case CEILLS:
170                UNOPsl("ceil.l.s");
171                printf("%s %lld %f\n",
172                       flt_round_op_names[op], fd_l, fs_f[i]);
173                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
174                break;
175             case CEILLD:
176                UNOPdl("ceil.l.d");
177                printf("%s %lld %lf\n",
178                       flt_round_op_names[op], fd_l, fs_d[i]);
179                printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
180                break;
181             default:
182                printf("error\n");
183                break;
184          }
185       }
186    }
187    return 0;
188 }
189 #endif
190 
191 
main()192 int main()
193 {
194 #if (__mips==32) && (__mips_isa_rev>=2) && \
195     ((__mips_fpr==64) || (__mips_fpr==xx))
196    flt_round_op_t op;
197    signal(SIGILL, handler);
198    /* Test fpu64 mode. */
199    TEST_FPU64;
200    printf("-------------------------- %s --------------------------\n",
201           "test FPU Conversion Operations Using the FCSR Rounding Mode");
202    for (op = CVTLS; op <= CEILLD; op++)
203       FCSRRoundingMode(op);
204 #else
205    PERROR;
206 #endif
207    return 0;
208 }
209 #else
main()210 int main() {
211    return 0;
212 }
213 #endif
214