Commit 65ce8c2fb438c8685dbcd28784a0b0ba2b484e5f

Authored by bellard
1 parent ee6c0b51

soft floats for SPARC (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2000 c046a42c-6fe2-441c-8c8c-71466251a162
configure
@@ -850,7 +850,7 @@ if test "$target_user_only" = "yes" ; then @@ -850,7 +850,7 @@ if test "$target_user_only" = "yes" ; then
850 echo "#define CONFIG_USER_ONLY 1" >> $config_h 850 echo "#define CONFIG_USER_ONLY 1" >> $config_h
851 fi 851 fi
852 852
853 -if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" ; then 853 +if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64"; then
854 echo "CONFIG_SOFTFLOAT=yes" >> $config_mak 854 echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
855 echo "#define CONFIG_SOFTFLOAT 1" >> $config_h 855 echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
856 fi 856 fi
target-sparc/cpu.h
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 #define TARGET_FPREGS 64 12 #define TARGET_FPREGS 64
13 #define TARGET_PAGE_BITS 12 /* XXX */ 13 #define TARGET_PAGE_BITS 12 /* XXX */
14 #endif 14 #endif
15 -#define TARGET_FPREG_T float 15 +#define TARGET_FPREG_T float32
16 16
17 #include "cpu-defs.h" 17 #include "cpu-defs.h"
18 18
@@ -146,7 +146,7 @@ @@ -146,7 +146,7 @@
146 typedef struct CPUSPARCState { 146 typedef struct CPUSPARCState {
147 target_ulong gregs[8]; /* general registers */ 147 target_ulong gregs[8]; /* general registers */
148 target_ulong *regwptr; /* pointer to current register window */ 148 target_ulong *regwptr; /* pointer to current register window */
149 - TARGET_FPREG_T fpr[TARGET_FPREGS]; /* floating point registers */ 149 + float32 fpr[TARGET_FPREGS]; /* floating point registers */
150 target_ulong pc; /* program counter */ 150 target_ulong pc; /* program counter */
151 target_ulong npc; /* next program counter */ 151 target_ulong npc; /* next program counter */
152 target_ulong y; /* multiply/divide register */ 152 target_ulong y; /* multiply/divide register */
@@ -187,8 +187,8 @@ typedef struct CPUSPARCState { @@ -187,8 +187,8 @@ typedef struct CPUSPARCState {
187 uint32_t mmuregs[16]; 187 uint32_t mmuregs[16];
188 #endif 188 #endif
189 /* temporary float registers */ 189 /* temporary float registers */
190 - float ft0, ft1;  
191 - double dt0, dt1; 190 + float32 ft0, ft1;
  191 + float64 dt0, dt1;
192 float_status fp_status; 192 float_status fp_status;
193 #if defined(TARGET_SPARC64) 193 #if defined(TARGET_SPARC64)
194 #define MAXTL 4 194 #define MAXTL 4
@@ -236,8 +236,6 @@ typedef struct CPUSPARCState { @@ -236,8 +236,6 @@ typedef struct CPUSPARCState {
236 CPUSPARCState *cpu_sparc_init(void); 236 CPUSPARCState *cpu_sparc_init(void);
237 int cpu_sparc_exec(CPUSPARCState *s); 237 int cpu_sparc_exec(CPUSPARCState *s);
238 int cpu_sparc_close(CPUSPARCState *s); 238 int cpu_sparc_close(CPUSPARCState *s);
239 -void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f);  
240 -double cpu_put_fp64(uint64_t mant, uint16_t exp);  
241 239
242 /* Fake impl 0, version 4 */ 240 /* Fake impl 0, version 4 */
243 #define GET_PSR(env) ((0 << 28) | (4 << 24) | (env->psr & PSR_ICC) | \ 241 #define GET_PSR(env) ((0 << 28) | (4 << 24) | (env->psr & PSR_ICC) | \
target-sparc/op.c
@@ -1339,94 +1339,66 @@ void OPPROTO op_flush_T0(void) @@ -1339,94 +1339,66 @@ void OPPROTO op_flush_T0(void)
1339 helper_flush(T0); 1339 helper_flush(T0);
1340 } 1340 }
1341 1341
1342 -void OPPROTO op_fnegs(void)  
1343 -{  
1344 - FT0 = -FT1;  
1345 -}  
1346 -  
1347 -void OPPROTO op_fabss(void)  
1348 -{  
1349 - do_fabss();  
1350 -}  
1351 -  
1352 -#ifdef TARGET_SPARC64  
1353 -void OPPROTO op_fnegd(void)  
1354 -{  
1355 - DT0 = -DT1;  
1356 -}  
1357 -  
1358 -void OPPROTO op_fabsd(void)  
1359 -{  
1360 - do_fabsd();  
1361 -}  
1362 -#endif  
1363 -  
1364 -void OPPROTO op_fsqrts(void)  
1365 -{  
1366 - do_fsqrts();  
1367 -}  
1368 -  
1369 -void OPPROTO op_fsqrtd(void)  
1370 -{  
1371 - do_fsqrtd();  
1372 -}  
1373 -  
1374 -void OPPROTO op_fmuls(void)  
1375 -{  
1376 - FT0 *= FT1;  
1377 -} 1342 +#define F_OP(name, p) void OPPROTO op_f##name##p(void)
  1343 +
  1344 +#define F_BINOP(name) \
  1345 + F_OP(name, s) \
  1346 + { \
  1347 + FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
  1348 + } \
  1349 + F_OP(name, d) \
  1350 + { \
  1351 + DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
  1352 + }
1378 1353
1379 -void OPPROTO op_fmuld(void)  
1380 -{  
1381 - DT0 *= DT1;  
1382 -} 1354 +F_BINOP(add);
  1355 +F_BINOP(sub);
  1356 +F_BINOP(mul);
  1357 +F_BINOP(div);
  1358 +#undef F_BINOP
1383 1359
1384 void OPPROTO op_fsmuld(void) 1360 void OPPROTO op_fsmuld(void)
1385 { 1361 {
1386 - DT0 = FT0 * FT1;  
1387 -}  
1388 -  
1389 -void OPPROTO op_fadds(void)  
1390 -{  
1391 - FT0 += FT1; 1362 + DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
  1363 + float32_to_float64(FT1, &env->fp_status),
  1364 + &env->fp_status);
1392 } 1365 }
1393 1366
1394 -void OPPROTO op_faddd(void)  
1395 -{  
1396 - DT0 += DT1;  
1397 -} 1367 +#define F_HELPER(name) \
  1368 + F_OP(name, s) \
  1369 + { \
  1370 + do_f##name##s(); \
  1371 + } \
  1372 + F_OP(name, d) \
  1373 + { \
  1374 + do_f##name##d(); \
  1375 + }
1398 1376
1399 -void OPPROTO op_fsubs(void)  
1400 -{  
1401 - FT0 -= FT1;  
1402 -} 1377 +F_HELPER(sqrt);
1403 1378
1404 -void OPPROTO op_fsubd(void) 1379 +F_OP(neg, s)
1405 { 1380 {
1406 - DT0 -= DT1; 1381 + FT0 = float32_chs(FT1);
1407 } 1382 }
1408 1383
1409 -void OPPROTO op_fdivs(void) 1384 +F_OP(abs, s)
1410 { 1385 {
1411 - FT0 /= FT1; 1386 + do_fabss();
1412 } 1387 }
1413 1388
1414 -void OPPROTO op_fdivd(void)  
1415 -{  
1416 - DT0 /= DT1;  
1417 -} 1389 +F_HELPER(cmp);
1418 1390
1419 -void OPPROTO op_fcmps(void) 1391 +#ifdef TARGET_SPARC64
  1392 +F_OP(neg, d)
1420 { 1393 {
1421 - do_fcmps(); 1394 + DT0 = float64_chs(DT1);
1422 } 1395 }
1423 1396
1424 -void OPPROTO op_fcmpd(void) 1397 +F_OP(abs, d)
1425 { 1398 {
1426 - do_fcmpd(); 1399 + do_fabsd();
1427 } 1400 }
1428 1401
1429 -#ifdef TARGET_SPARC64  
1430 void OPPROTO op_fcmps_fcc1(void) 1402 void OPPROTO op_fcmps_fcc1(void)
1431 { 1403 {
1432 do_fcmps_fcc1(); 1404 do_fcmps_fcc1();
@@ -1458,69 +1430,65 @@ void OPPROTO op_fcmpd_fcc3(void) @@ -1458,69 +1430,65 @@ void OPPROTO op_fcmpd_fcc3(void)
1458 } 1430 }
1459 #endif 1431 #endif
1460 1432
  1433 +/* Integer to float conversion. */
1461 #ifdef USE_INT_TO_FLOAT_HELPERS 1434 #ifdef USE_INT_TO_FLOAT_HELPERS
1462 -void OPPROTO op_fitos(void)  
1463 -{  
1464 - do_fitos();  
1465 -}  
1466 -  
1467 -void OPPROTO op_fitod(void)  
1468 -{  
1469 - do_fitod();  
1470 -} 1435 +F_HELPER(ito);
1471 #else 1436 #else
1472 -void OPPROTO op_fitos(void) 1437 +F_OP(ito, s)
1473 { 1438 {
1474 - FT0 = (float) *((int32_t *)&FT1); 1439 + FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
1475 } 1440 }
1476 1441
1477 -void OPPROTO op_fitod(void) 1442 +F_OP(ito, d)
1478 { 1443 {
1479 - DT0 = (double) *((int32_t *)&FT1); 1444 + DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
1480 } 1445 }
1481 1446
1482 #ifdef TARGET_SPARC64 1447 #ifdef TARGET_SPARC64
1483 -void OPPROTO op_fxtos(void) 1448 +F_OP(xto, s)
1484 { 1449 {
1485 - FT0 = (float) *((int64_t *)&DT1); 1450 + FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
1486 } 1451 }
1487 1452
1488 -void OPPROTO op_fxtod(void) 1453 +F_OP(xto, d)
1489 { 1454 {
1490 - DT0 = (double) *((int64_t *)&DT1); 1455 + DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
1491 } 1456 }
1492 #endif 1457 #endif
1493 #endif 1458 #endif
  1459 +#undef F_HELPER
1494 1460
  1461 +/* floating point conversion */
1495 void OPPROTO op_fdtos(void) 1462 void OPPROTO op_fdtos(void)
1496 { 1463 {
1497 - FT0 = (float) DT1; 1464 + FT0 = float64_to_float32(DT1, &env->fp_status);
1498 } 1465 }
1499 1466
1500 void OPPROTO op_fstod(void) 1467 void OPPROTO op_fstod(void)
1501 { 1468 {
1502 - DT0 = (double) FT1; 1469 + DT0 = float32_to_float64(FT1, &env->fp_status);
1503 } 1470 }
1504 1471
  1472 +/* Float to integer conversion. */
1505 void OPPROTO op_fstoi(void) 1473 void OPPROTO op_fstoi(void)
1506 { 1474 {
1507 - *((int32_t *)&FT0) = (int32_t) FT1; 1475 + *((int32_t *)&FT0) = float32_to_int32(FT1, &env->fp_status);
1508 } 1476 }
1509 1477
1510 void OPPROTO op_fdtoi(void) 1478 void OPPROTO op_fdtoi(void)
1511 { 1479 {
1512 - *((int32_t *)&FT0) = (int32_t) DT1; 1480 + *((int32_t *)&FT0) = float64_to_int32(DT1, &env->fp_status);
1513 } 1481 }
1514 1482
1515 #ifdef TARGET_SPARC64 1483 #ifdef TARGET_SPARC64
1516 void OPPROTO op_fstox(void) 1484 void OPPROTO op_fstox(void)
1517 { 1485 {
1518 - *((int64_t *)&DT0) = (int64_t) FT1; 1486 + *((int64_t *)&DT0) = float32_to_int64(FT1, &env->fp_status);
1519 } 1487 }
1520 1488
1521 void OPPROTO op_fdtox(void) 1489 void OPPROTO op_fdtox(void)
1522 { 1490 {
1523 - *((int64_t *)&DT0) = (int64_t) DT1; 1491 + *((int64_t *)&DT0) = float64_to_int64(DT1, &env->fp_status);
1524 } 1492 }
1525 1493
1526 void OPPROTO op_fmovs_cc(void) 1494 void OPPROTO op_fmovs_cc(void)
target-sparc/op_helper.c
@@ -12,12 +12,12 @@ void raise_exception(int tt) @@ -12,12 +12,12 @@ void raise_exception(int tt)
12 #ifdef USE_INT_TO_FLOAT_HELPERS 12 #ifdef USE_INT_TO_FLOAT_HELPERS
13 void do_fitos(void) 13 void do_fitos(void)
14 { 14 {
15 - FT0 = (float) *((int32_t *)&FT1); 15 + FT0 = int32_to_float32(*((int32_t *)&FT1));
16 } 16 }
17 17
18 void do_fitod(void) 18 void do_fitod(void)
19 { 19 {
20 - DT0 = (double) *((int32_t *)&FT1); 20 + DT0 = int32_to_float64(*((int32_t *)&FT1));
21 } 21 }
22 #endif 22 #endif
23 23
@@ -43,182 +43,45 @@ void do_fsqrtd(void) @@ -43,182 +43,45 @@ void do_fsqrtd(void)
43 DT0 = float64_sqrt(DT1, &env->fp_status); 43 DT0 = float64_sqrt(DT1, &env->fp_status);
44 } 44 }
45 45
46 -#define FS 0  
47 -void do_fcmps (void)  
48 -{  
49 - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);  
50 - if (isnan(FT0) || isnan(FT1)) {  
51 - T0 = (FSR_FCC1 | FSR_FCC0) << FS;  
52 - if (env->fsr & FSR_NVM) {  
53 - env->fsr |= T0;  
54 - raise_exception(TT_FP_EXCP);  
55 - } else {  
56 - env->fsr |= FSR_NVA;  
57 - }  
58 - } else if (FT0 < FT1) {  
59 - T0 = FSR_FCC0 << FS;  
60 - } else if (FT0 > FT1) {  
61 - T0 = FSR_FCC1 << FS;  
62 - } else {  
63 - T0 = 0; 46 +#define GEN_FCMP(name, size, reg1, reg2, FS) \
  47 + void glue(do_, name) (void) \
  48 + { \
  49 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
  50 + switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \
  51 + case float_relation_unordered: \
  52 + T0 = (FSR_FCC1 | FSR_FCC0) << FS; \
  53 + if (env->fsr & FSR_NVM) { \
  54 + env->fsr |= T0; \
  55 + raise_exception(TT_FP_EXCP); \
  56 + } else { \
  57 + env->fsr |= FSR_NVA; \
  58 + } \
  59 + break; \
  60 + case float_relation_less: \
  61 + T0 = FSR_FCC0 << FS; \
  62 + break; \
  63 + case float_relation_greater: \
  64 + T0 = FSR_FCC1 << FS; \
  65 + break; \
  66 + default: \
  67 + T0 = 0; \
  68 + break; \
  69 + } \
  70 + env->fsr |= T0; \
64 } 71 }
65 - env->fsr |= T0;  
66 -}  
67 72
68 -void do_fcmpd (void)  
69 -{  
70 - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);  
71 - if (isnan(DT0) || isnan(DT1)) {  
72 - T0 = (FSR_FCC1 | FSR_FCC0) << FS;  
73 - if (env->fsr & FSR_NVM) {  
74 - env->fsr |= T0;  
75 - raise_exception(TT_FP_EXCP);  
76 - } else {  
77 - env->fsr |= FSR_NVA;  
78 - }  
79 - } else if (DT0 < DT1) {  
80 - T0 = FSR_FCC0 << FS;  
81 - } else if (DT0 > DT1) {  
82 - T0 = FSR_FCC1 << FS;  
83 - } else {  
84 - T0 = 0;  
85 - }  
86 - env->fsr |= T0;  
87 -} 73 +GEN_FCMP(fcmps, float32, FT0, FT1, 0);
  74 +GEN_FCMP(fcmpd, float64, DT0, DT1, 0);
88 75
89 #ifdef TARGET_SPARC64 76 #ifdef TARGET_SPARC64
90 -#undef FS  
91 -#define FS 22  
92 -void do_fcmps_fcc1 (void)  
93 -{  
94 - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);  
95 - if (isnan(FT0) || isnan(FT1)) {  
96 - T0 = (FSR_FCC1 | FSR_FCC0) << FS;  
97 - if (env->fsr & FSR_NVM) {  
98 - env->fsr |= T0;  
99 - raise_exception(TT_FP_EXCP);  
100 - } else {  
101 - env->fsr |= FSR_NVA;  
102 - }  
103 - } else if (FT0 < FT1) {  
104 - T0 = FSR_FCC0 << FS;  
105 - } else if (FT0 > FT1) {  
106 - T0 = FSR_FCC1 << FS;  
107 - } else {  
108 - T0 = 0;  
109 - }  
110 - env->fsr |= T0;  
111 -}  
112 -  
113 -void do_fcmpd_fcc1 (void)  
114 -{  
115 - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);  
116 - if (isnan(DT0) || isnan(DT1)) {  
117 - T0 = (FSR_FCC1 | FSR_FCC0) << FS;  
118 - if (env->fsr & FSR_NVM) {  
119 - env->fsr |= T0;  
120 - raise_exception(TT_FP_EXCP);  
121 - } else {  
122 - env->fsr |= FSR_NVA;  
123 - }  
124 - } else if (DT0 < DT1) {  
125 - T0 = FSR_FCC0 << FS;  
126 - } else if (DT0 > DT1) {  
127 - T0 = FSR_FCC1 << FS;  
128 - } else {  
129 - T0 = 0;  
130 - }  
131 - env->fsr |= T0;  
132 -} 77 +GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22);
  78 +GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22);
133 79
134 -#undef FS  
135 -#define FS 24  
136 -void do_fcmps_fcc2 (void)  
137 -{  
138 - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);  
139 - if (isnan(FT0) || isnan(FT1)) {  
140 - T0 = (FSR_FCC1 | FSR_FCC0) << FS;  
141 - if (env->fsr & FSR_NVM) {  
142 - env->fsr |= T0;  
143 - raise_exception(TT_FP_EXCP);  
144 - } else {  
145 - env->fsr |= FSR_NVA;  
146 - }  
147 - } else if (FT0 < FT1) {  
148 - T0 = FSR_FCC0 << FS;  
149 - } else if (FT0 > FT1) {  
150 - T0 = FSR_FCC1 << FS;  
151 - } else {  
152 - T0 = 0;  
153 - }  
154 - env->fsr |= T0;  
155 -} 80 +GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24);
  81 +GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24);
156 82
157 -void do_fcmpd_fcc2 (void)  
158 -{  
159 - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);  
160 - if (isnan(DT0) || isnan(DT1)) {  
161 - T0 = (FSR_FCC1 | FSR_FCC0) << FS;  
162 - if (env->fsr & FSR_NVM) {  
163 - env->fsr |= T0;  
164 - raise_exception(TT_FP_EXCP);  
165 - } else {  
166 - env->fsr |= FSR_NVA;  
167 - }  
168 - } else if (DT0 < DT1) {  
169 - T0 = FSR_FCC0 << FS;  
170 - } else if (DT0 > DT1) {  
171 - T0 = FSR_FCC1 << FS;  
172 - } else {  
173 - T0 = 0;  
174 - }  
175 - env->fsr |= T0;  
176 -}  
177 -  
178 -#undef FS  
179 -#define FS 26  
180 -void do_fcmps_fcc3 (void)  
181 -{  
182 - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);  
183 - if (isnan(FT0) || isnan(FT1)) {  
184 - T0 = (FSR_FCC1 | FSR_FCC0) << FS;  
185 - if (env->fsr & FSR_NVM) {  
186 - env->fsr |= T0;  
187 - raise_exception(TT_FP_EXCP);  
188 - } else {  
189 - env->fsr |= FSR_NVA;  
190 - }  
191 - } else if (FT0 < FT1) {  
192 - T0 = FSR_FCC0 << FS;  
193 - } else if (FT0 > FT1) {  
194 - T0 = FSR_FCC1 << FS;  
195 - } else {  
196 - T0 = 0;  
197 - }  
198 - env->fsr |= T0;  
199 -}  
200 -  
201 -void do_fcmpd_fcc3 (void)  
202 -{  
203 - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);  
204 - if (isnan(DT0) || isnan(DT1)) {  
205 - T0 = (FSR_FCC1 | FSR_FCC0) << FS;  
206 - if (env->fsr & FSR_NVM) {  
207 - env->fsr |= T0;  
208 - raise_exception(TT_FP_EXCP);  
209 - } else {  
210 - env->fsr |= FSR_NVA;  
211 - }  
212 - } else if (DT0 < DT1) {  
213 - T0 = FSR_FCC0 << FS;  
214 - } else if (DT0 > DT1) {  
215 - T0 = FSR_FCC1 << FS;  
216 - } else {  
217 - T0 = 0;  
218 - }  
219 - env->fsr |= T0;  
220 -}  
221 -#undef FS 83 +GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26);
  84 +GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26);
222 #endif 85 #endif
223 86
224 #if defined(CONFIG_USER_ONLY) 87 #if defined(CONFIG_USER_ONLY)
@@ -783,19 +646,6 @@ void helper_ldfsr(void) @@ -783,19 +646,6 @@ void helper_ldfsr(void)
783 set_float_rounding_mode(rnd_mode, &env->fp_status); 646 set_float_rounding_mode(rnd_mode, &env->fp_status);
784 } 647 }
785 648
786 -void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f)  
787 -{  
788 - int exptemp;  
789 -  
790 - *pmant = ldexp(frexp(f, &exptemp), 53);  
791 - *pexp = exptemp;  
792 -}  
793 -  
794 -double cpu_put_fp64(uint64_t mant, uint16_t exp)  
795 -{  
796 - return ldexp((double) mant, exp - 53);  
797 -}  
798 -  
799 void helper_debug() 649 void helper_debug()
800 { 650 {
801 env->exception_index = EXCP_DEBUG; 651 env->exception_index = EXCP_DEBUG;