blob: a4715f2a03124cb262adacc6ed7b025304286612 [file] [log] [blame]
Elliott Hughesa0664b92017-04-18 17:46:52 -07001#if defined(__mips_hard_float)
2
dejanj24f0c3a2014-02-19 11:57:22 +00003#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
13typedef enum {
14 CVTLS, CVTLD, ROUNDLS, ROUNDLD,
15 TRUNCLS, TRUNCLD, FLOORLS, FLOORLD,
16 CEILLS, CEILLD
17} flt_round_op_t;
18
19const 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
25typedef enum {
26 TO_NEAREST=0, TO_ZERO, TO_PLUS_INFINITY, TO_MINUS_INFINITY } round_mode_t;
27char *round_mode_name[] = { "near", "zero", "+inf", "-inf" };
28
29const 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
38const 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) && (__mips_fpr==64)
76void set_rounding_mode(round_mode_t mode)
77{
78 switch(mode) {
79 case TO_NEAREST:
80 __asm__ volatile("ctc1 $zero, $31" "\n\t");
81 break;
82 case TO_ZERO:
83 __asm__ volatile("li $t0, 0x1" "\n\t"
84 "ctc1 $t0, $31" "\n\t");
85 break;
86 case TO_PLUS_INFINITY:
87 __asm__ volatile("li $t0, 0x2" "\n\t"
88 "ctc1 $t0, $31" "\n\t");
89 break;
90 case TO_MINUS_INFINITY:
91 __asm__ volatile("li $t0, 0x3" "\n\t"
92 "ctc1 $t0, $31" "\n\t");
93 break;
94 }
95}
96
97struct test {
98 void (*test)(void);
99 int sig;
100 int code;
101};
102
103static void handler(int sig)
104{
105 PERROR;
106 exit(0);
107}
108
109int FCSRRoundingMode(flt_round_op_t op)
110{
111 long long int fd_l;
112 int i;
113 int fcsr = 0;
114 round_mode_t rm;
115 for (rm = TO_NEAREST; rm <= TO_MINUS_INFINITY; rm ++) {
116 printf("roundig mode: %s\n", round_mode_name[rm]);
117 for (i = 0; i < MAX_ARR; i++) {
118 set_rounding_mode(rm);
119 switch(op) {
120 case CVTLS:
121 UNOPsl("cvt.l.s");
122 printf("%s %lld %f\n",
123 flt_round_op_names[op], fd_l, fs_f[i]);
124 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
125 break;
126 case CVTLD:
127 UNOPdl("cvt.l.d");
128 printf("%s %lld %lf\n",
129 flt_round_op_names[op], fd_l, fs_d[i]);
130 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
131 break;
132 case ROUNDLS:
133 UNOPsl("round.l.s");
134 printf("%s %lld %f\n",
135 flt_round_op_names[op], fd_l, fs_f[i]);
136 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
137 break;
138 case ROUNDLD:
139 UNOPdl("round.l.d");
140 printf("%s %lld %lf\n",
141 flt_round_op_names[op], fd_l, fs_d[i]);
142 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
143 break;
144 case TRUNCLS:
145 UNOPsl("trunc.l.s");
146 printf("%s %lld %f\n",
147 flt_round_op_names[op], fd_l, fs_f[i]);
148 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
149 break;
150 case TRUNCLD:
151 UNOPdl("trunc.l.d");
152 printf("%s %lld %lf\n",
153 flt_round_op_names[op], fd_l, fs_d[i]);
154 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
155 break;
156 case FLOORLS:
157 UNOPsl("floor.l.s");
158 printf("%s %lld %f\n",
159 flt_round_op_names[op], fd_l, fs_f[i]);
160 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
161 break;
162 case FLOORLD:
163 UNOPdl("floor.l.d");
164 printf("%s %lld %lf\n",
165 flt_round_op_names[op], fd_l, fs_d[i]);
166 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
167 break;
168 case CEILLS:
169 UNOPsl("ceil.l.s");
170 printf("%s %lld %f\n",
171 flt_round_op_names[op], fd_l, fs_f[i]);
172 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
173 break;
174 case CEILLD:
175 UNOPdl("ceil.l.d");
176 printf("%s %lld %lf\n",
177 flt_round_op_names[op], fd_l, fs_d[i]);
178 printf("fcsr: 0x%x\n", fcsr & FLAGS_RM_MASK);
179 break;
180 default:
181 printf("error\n");
182 break;
183 }
184 }
185 }
186 return 0;
187}
188#endif
189
190
191int main()
192{
193#if (__mips==32) && (__mips_isa_rev>=2) && (__mips_fpr==64)
194 flt_round_op_t op;
195 signal(SIGILL, handler);
196 /* Test fpu64 mode. */
197 TEST_FPU64;
198 printf("-------------------------- %s --------------------------\n",
199 "test FPU Conversion Operations Using the FCSR Rounding Mode");
200 for (op = CVTLS; op <= CEILLD; op++)
201 FCSRRoundingMode(op);
202#else
203 PERROR;
204#endif
205 return 0;
206}
Elliott Hughesa0664b92017-04-18 17:46:52 -0700207#else
208int main() {
209 return 0;
210}
211#endif