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 850 echo "#define CONFIG_USER_ONLY 1" >> $config_h
851 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 854 echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
855 855 echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
856 856 fi
... ...
target-sparc/cpu.h
... ... @@ -12,7 +12,7 @@
12 12 #define TARGET_FPREGS 64
13 13 #define TARGET_PAGE_BITS 12 /* XXX */
14 14 #endif
15   -#define TARGET_FPREG_T float
  15 +#define TARGET_FPREG_T float32
16 16  
17 17 #include "cpu-defs.h"
18 18  
... ... @@ -146,7 +146,7 @@
146 146 typedef struct CPUSPARCState {
147 147 target_ulong gregs[8]; /* general registers */
148 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 150 target_ulong pc; /* program counter */
151 151 target_ulong npc; /* next program counter */
152 152 target_ulong y; /* multiply/divide register */
... ... @@ -187,8 +187,8 @@ typedef struct CPUSPARCState {
187 187 uint32_t mmuregs[16];
188 188 #endif
189 189 /* temporary float registers */
190   - float ft0, ft1;
191   - double dt0, dt1;
  190 + float32 ft0, ft1;
  191 + float64 dt0, dt1;
192 192 float_status fp_status;
193 193 #if defined(TARGET_SPARC64)
194 194 #define MAXTL 4
... ... @@ -236,8 +236,6 @@ typedef struct CPUSPARCState {
236 236 CPUSPARCState *cpu_sparc_init(void);
237 237 int cpu_sparc_exec(CPUSPARCState *s);
238 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 240 /* Fake impl 0, version 4 */
243 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 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 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 1402 void OPPROTO op_fcmps_fcc1(void)
1431 1403 {
1432 1404 do_fcmps_fcc1();
... ... @@ -1458,69 +1430,65 @@ void OPPROTO op_fcmpd_fcc3(void)
1458 1430 }
1459 1431 #endif
1460 1432  
  1433 +/* Integer to float conversion. */
1461 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 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 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 1457 #endif
1493 1458 #endif
  1459 +#undef F_HELPER
1494 1460  
  1461 +/* floating point conversion */
1495 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 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 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 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 1483 #ifdef TARGET_SPARC64
1516 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 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 1494 void OPPROTO op_fmovs_cc(void)
... ...
target-sparc/op_helper.c
... ... @@ -12,12 +12,12 @@ void raise_exception(int tt)
12 12 #ifdef USE_INT_TO_FLOAT_HELPERS
13 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 18 void do_fitod(void)
19 19 {
20   - DT0 = (double) *((int32_t *)&FT1);
  20 + DT0 = int32_to_float64(*((int32_t *)&FT1));
21 21 }
22 22 #endif
23 23  
... ... @@ -43,182 +43,45 @@ void do_fsqrtd(void)
43 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 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 85 #endif
223 86  
224 87 #if defined(CONFIG_USER_ONLY)
... ... @@ -783,19 +646,6 @@ void helper_ldfsr(void)
783 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 649 void helper_debug()
800 650 {
801 651 env->exception_index = EXCP_DEBUG;
... ...