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