Revision 417454b0
b/target-sparc/exec.h | ||
---|---|---|
61 | 61 |
void do_fsqrtd(void); |
62 | 62 |
void do_fcmps(void); |
63 | 63 |
void do_fcmpd(void); |
64 |
void do_fcmpes(void); |
|
65 |
void do_fcmped(void); |
|
64 | 66 |
#ifdef TARGET_SPARC64 |
65 | 67 |
void do_fabsd(void); |
66 | 68 |
void do_fcmps_fcc1(void); |
... | ... | |
69 | 71 |
void do_fcmpd_fcc2(void); |
70 | 72 |
void do_fcmps_fcc3(void); |
71 | 73 |
void do_fcmpd_fcc3(void); |
74 |
void do_fcmpes_fcc1(void); |
|
75 |
void do_fcmped_fcc1(void); |
|
76 |
void do_fcmpes_fcc2(void); |
|
77 |
void do_fcmped_fcc2(void); |
|
78 |
void do_fcmpes_fcc3(void); |
|
79 |
void do_fcmped_fcc3(void); |
|
72 | 80 |
void do_popc(); |
73 | 81 |
void do_wrpstate(); |
74 | 82 |
void do_done(); |
... | ... | |
79 | 87 |
void do_ldd_raw(target_ulong addr); |
80 | 88 |
void do_interrupt(int intno); |
81 | 89 |
void raise_exception(int tt); |
90 |
void check_ieee_exceptions(); |
|
82 | 91 |
void memcpy32(target_ulong *dst, const target_ulong *src); |
83 | 92 |
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); |
84 | 93 |
void dump_mmu(CPUState *env); |
b/target-sparc/op.c | ||
---|---|---|
1534 | 1534 |
helper_flush(T0); |
1535 | 1535 |
} |
1536 | 1536 |
|
1537 |
void OPPROTO op_clear_ieee_excp_and_FTT(void) |
|
1538 |
{ |
|
1539 |
env->fsr &= ~(FSR_FTT_MASK | FSR_CEXC_MASK);; |
|
1540 |
} |
|
1541 |
|
|
1537 | 1542 |
#define F_OP(name, p) void OPPROTO op_f##name##p(void) |
1538 | 1543 |
|
1539 | 1544 |
#define F_BINOP(name) \ |
1540 | 1545 |
F_OP(name, s) \ |
1541 | 1546 |
{ \ |
1547 |
set_float_exception_flags(0, &env->fp_status); \ |
|
1542 | 1548 |
FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \ |
1549 |
check_ieee_exceptions(); \ |
|
1543 | 1550 |
} \ |
1544 | 1551 |
F_OP(name, d) \ |
1545 | 1552 |
{ \ |
1553 |
set_float_exception_flags(0, &env->fp_status); \ |
|
1546 | 1554 |
DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \ |
1555 |
check_ieee_exceptions(); \ |
|
1547 | 1556 |
} |
1548 | 1557 |
|
1549 | 1558 |
F_BINOP(add); |
... | ... | |
1554 | 1563 |
|
1555 | 1564 |
void OPPROTO op_fsmuld(void) |
1556 | 1565 |
{ |
1566 |
set_float_exception_flags(0, &env->fp_status); |
|
1557 | 1567 |
DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status), |
1558 | 1568 |
float32_to_float64(FT1, &env->fp_status), |
1559 | 1569 |
&env->fp_status); |
1570 |
check_ieee_exceptions(); |
|
1560 | 1571 |
} |
1561 | 1572 |
|
1562 | 1573 |
#define F_HELPER(name) \ |
... | ... | |
1582 | 1593 |
} |
1583 | 1594 |
|
1584 | 1595 |
F_HELPER(cmp); |
1596 |
F_HELPER(cmpe); |
|
1585 | 1597 |
|
1586 | 1598 |
#ifdef TARGET_SPARC64 |
1587 | 1599 |
F_OP(neg, d) |
... | ... | |
1623 | 1635 |
{ |
1624 | 1636 |
do_fcmpd_fcc3(); |
1625 | 1637 |
} |
1638 |
|
|
1639 |
void OPPROTO op_fcmpes_fcc1(void) |
|
1640 |
{ |
|
1641 |
do_fcmpes_fcc1(); |
|
1642 |
} |
|
1643 |
|
|
1644 |
void OPPROTO op_fcmped_fcc1(void) |
|
1645 |
{ |
|
1646 |
do_fcmped_fcc1(); |
|
1647 |
} |
|
1648 |
|
|
1649 |
void OPPROTO op_fcmpes_fcc2(void) |
|
1650 |
{ |
|
1651 |
do_fcmpes_fcc2(); |
|
1652 |
} |
|
1653 |
|
|
1654 |
void OPPROTO op_fcmped_fcc2(void) |
|
1655 |
{ |
|
1656 |
do_fcmped_fcc2(); |
|
1657 |
} |
|
1658 |
|
|
1659 |
void OPPROTO op_fcmpes_fcc3(void) |
|
1660 |
{ |
|
1661 |
do_fcmpes_fcc3(); |
|
1662 |
} |
|
1663 |
|
|
1664 |
void OPPROTO op_fcmped_fcc3(void) |
|
1665 |
{ |
|
1666 |
do_fcmped_fcc3(); |
|
1667 |
} |
|
1668 |
|
|
1626 | 1669 |
#endif |
1627 | 1670 |
|
1628 | 1671 |
/* Integer to float conversion. */ |
... | ... | |
1631 | 1674 |
#else |
1632 | 1675 |
F_OP(ito, s) |
1633 | 1676 |
{ |
1677 |
set_float_exception_flags(0, &env->fp_status); |
|
1634 | 1678 |
FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); |
1679 |
check_ieee_exceptions(); |
|
1635 | 1680 |
} |
1636 | 1681 |
|
1637 | 1682 |
F_OP(ito, d) |
1638 | 1683 |
{ |
1684 |
set_float_exception_flags(0, &env->fp_status); |
|
1639 | 1685 |
DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status); |
1686 |
check_ieee_exceptions(); |
|
1640 | 1687 |
} |
1641 | 1688 |
|
1642 | 1689 |
#ifdef TARGET_SPARC64 |
1643 | 1690 |
F_OP(xto, s) |
1644 | 1691 |
{ |
1692 |
set_float_exception_flags(0, &env->fp_status); |
|
1645 | 1693 |
FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status); |
1694 |
check_ieee_exceptions(); |
|
1646 | 1695 |
} |
1647 | 1696 |
|
1648 | 1697 |
F_OP(xto, d) |
1649 | 1698 |
{ |
1699 |
set_float_exception_flags(0, &env->fp_status); |
|
1650 | 1700 |
DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status); |
1701 |
check_ieee_exceptions(); |
|
1651 | 1702 |
} |
1652 | 1703 |
#endif |
1653 | 1704 |
#endif |
... | ... | |
1656 | 1707 |
/* floating point conversion */ |
1657 | 1708 |
void OPPROTO op_fdtos(void) |
1658 | 1709 |
{ |
1710 |
set_float_exception_flags(0, &env->fp_status); |
|
1659 | 1711 |
FT0 = float64_to_float32(DT1, &env->fp_status); |
1712 |
check_ieee_exceptions(); |
|
1660 | 1713 |
} |
1661 | 1714 |
|
1662 | 1715 |
void OPPROTO op_fstod(void) |
1663 | 1716 |
{ |
1717 |
set_float_exception_flags(0, &env->fp_status); |
|
1664 | 1718 |
DT0 = float32_to_float64(FT1, &env->fp_status); |
1719 |
check_ieee_exceptions(); |
|
1665 | 1720 |
} |
1666 | 1721 |
|
1667 | 1722 |
/* Float to integer conversion. */ |
1668 | 1723 |
void OPPROTO op_fstoi(void) |
1669 | 1724 |
{ |
1725 |
set_float_exception_flags(0, &env->fp_status); |
|
1670 | 1726 |
*((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status); |
1727 |
check_ieee_exceptions(); |
|
1671 | 1728 |
} |
1672 | 1729 |
|
1673 | 1730 |
void OPPROTO op_fdtoi(void) |
1674 | 1731 |
{ |
1732 |
set_float_exception_flags(0, &env->fp_status); |
|
1675 | 1733 |
*((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status); |
1734 |
check_ieee_exceptions(); |
|
1676 | 1735 |
} |
1677 | 1736 |
|
1678 | 1737 |
#ifdef TARGET_SPARC64 |
1679 | 1738 |
void OPPROTO op_fstox(void) |
1680 | 1739 |
{ |
1740 |
set_float_exception_flags(0, &env->fp_status); |
|
1681 | 1741 |
*((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status); |
1742 |
check_ieee_exceptions(); |
|
1682 | 1743 |
} |
1683 | 1744 |
|
1684 | 1745 |
void OPPROTO op_fdtox(void) |
1685 | 1746 |
{ |
1747 |
set_float_exception_flags(0, &env->fp_status); |
|
1686 | 1748 |
*((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status); |
1749 |
check_ieee_exceptions(); |
|
1687 | 1750 |
} |
1688 | 1751 |
|
1689 | 1752 |
void OPPROTO op_fmovs_cc(void) |
b/target-sparc/op_helper.c | ||
---|---|---|
9 | 9 |
cpu_loop_exit(); |
10 | 10 |
} |
11 | 11 |
|
12 |
void check_ieee_exceptions() |
|
13 |
{ |
|
14 |
T0 = get_float_exception_flags(&env->fp_status); |
|
15 |
if (T0) |
|
16 |
{ |
|
17 |
/* Copy IEEE 754 flags into FSR */ |
|
18 |
if (T0 & float_flag_invalid) |
|
19 |
env->fsr |= FSR_NVC; |
|
20 |
if (T0 & float_flag_overflow) |
|
21 |
env->fsr |= FSR_OFC; |
|
22 |
if (T0 & float_flag_underflow) |
|
23 |
env->fsr |= FSR_UFC; |
|
24 |
if (T0 & float_flag_divbyzero) |
|
25 |
env->fsr |= FSR_DZC; |
|
26 |
if (T0 & float_flag_inexact) |
|
27 |
env->fsr |= FSR_NXC; |
|
28 |
|
|
29 |
if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) |
|
30 |
{ |
|
31 |
/* Unmasked exception, generate a trap */ |
|
32 |
env->fsr |= FSR_FTT_IEEE_EXCP; |
|
33 |
raise_exception(TT_FP_EXCP); |
|
34 |
} |
|
35 |
else |
|
36 |
{ |
|
37 |
/* Accumulate exceptions */ |
|
38 |
env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5; |
|
39 |
} |
|
40 |
} |
|
41 |
} |
|
42 |
|
|
12 | 43 |
#ifdef USE_INT_TO_FLOAT_HELPERS |
13 | 44 |
void do_fitos(void) |
14 | 45 |
{ |
46 |
set_float_exception_flags(0, &env->fp_status); |
|
15 | 47 |
FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); |
48 |
check_ieee_exceptions(); |
|
16 | 49 |
} |
17 | 50 |
|
18 | 51 |
void do_fitod(void) |
... | ... | |
35 | 68 |
|
36 | 69 |
void do_fsqrts(void) |
37 | 70 |
{ |
71 |
set_float_exception_flags(0, &env->fp_status); |
|
38 | 72 |
FT0 = float32_sqrt(FT1, &env->fp_status); |
73 |
check_ieee_exceptions(); |
|
39 | 74 |
} |
40 | 75 |
|
41 | 76 |
void do_fsqrtd(void) |
42 | 77 |
{ |
78 |
set_float_exception_flags(0, &env->fp_status); |
|
43 | 79 |
DT0 = float64_sqrt(DT1, &env->fp_status); |
80 |
check_ieee_exceptions(); |
|
44 | 81 |
} |
45 | 82 |
|
46 |
#define GEN_FCMP(name, size, reg1, reg2, FS) \
|
|
83 |
#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP) \
|
|
47 | 84 |
void glue(do_, name) (void) \ |
48 | 85 |
{ \ |
49 | 86 |
env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
50 | 87 |
switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \ |
51 | 88 |
case float_relation_unordered: \ |
52 | 89 |
T0 = (FSR_FCC1 | FSR_FCC0) << FS; \ |
53 |
if (env->fsr & FSR_NVM) { \
|
|
90 |
if ((env->fsr & FSR_NVM) || TRAP) { \
|
|
54 | 91 |
env->fsr |= T0; \ |
92 |
env->fsr |= FSR_NVC; \ |
|
93 |
env->fsr |= FSR_FTT_IEEE_EXCP; \ |
|
55 | 94 |
raise_exception(TT_FP_EXCP); \ |
56 | 95 |
} else { \ |
57 | 96 |
env->fsr |= FSR_NVA; \ |
... | ... | |
70 | 109 |
env->fsr |= T0; \ |
71 | 110 |
} |
72 | 111 |
|
73 |
GEN_FCMP(fcmps, float32, FT0, FT1, 0); |
|
74 |
GEN_FCMP(fcmpd, float64, DT0, DT1, 0); |
|
112 |
GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0); |
|
113 |
GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0); |
|
114 |
|
|
115 |
GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1); |
|
116 |
GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1); |
|
75 | 117 |
|
76 | 118 |
#ifdef TARGET_SPARC64 |
77 |
GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22); |
|
78 |
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22); |
|
119 |
GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0); |
|
120 |
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0); |
|
121 |
|
|
122 |
GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0); |
|
123 |
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0); |
|
124 |
|
|
125 |
GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0); |
|
126 |
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0); |
|
127 |
|
|
128 |
GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1); |
|
129 |
GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1); |
|
79 | 130 |
|
80 |
GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24);
|
|
81 |
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24);
|
|
131 |
GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1);
|
|
132 |
GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
|
|
82 | 133 |
|
83 |
GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26);
|
|
84 |
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26);
|
|
134 |
GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
|
|
135 |
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
|
|
85 | 136 |
#endif |
86 | 137 |
|
87 | 138 |
#if defined(CONFIG_USER_ONLY) |
b/target-sparc/translate.c | ||
---|---|---|
943 | 943 |
gen_op_fcmpd_fcc2, |
944 | 944 |
gen_op_fcmpd_fcc3, |
945 | 945 |
}; |
946 |
|
|
947 |
static GenOpFunc * const gen_fcmpes[4] = { |
|
948 |
gen_op_fcmpes, |
|
949 |
gen_op_fcmpes_fcc1, |
|
950 |
gen_op_fcmpes_fcc2, |
|
951 |
gen_op_fcmpes_fcc3, |
|
952 |
}; |
|
953 |
|
|
954 |
static GenOpFunc * const gen_fcmped[4] = { |
|
955 |
gen_op_fcmped, |
|
956 |
gen_op_fcmped_fcc1, |
|
957 |
gen_op_fcmped_fcc2, |
|
958 |
gen_op_fcmped_fcc3, |
|
959 |
}; |
|
960 |
|
|
946 | 961 |
#endif |
947 | 962 |
|
948 | 963 |
static int gen_trap_ifnofpu(DisasContext * dc) |
... | ... | |
1289 | 1304 |
} else if (xop == 0x34) { /* FPU Operations */ |
1290 | 1305 |
if (gen_trap_ifnofpu(dc)) |
1291 | 1306 |
goto jmp_insn; |
1307 |
gen_op_clear_ieee_excp_and_FTT(); |
|
1292 | 1308 |
rs1 = GET_FIELD(insn, 13, 17); |
1293 | 1309 |
rs2 = GET_FIELD(insn, 27, 31); |
1294 | 1310 |
xop = GET_FIELD(insn, 18, 26); |
... | ... | |
1476 | 1492 |
#endif |
1477 | 1493 |
if (gen_trap_ifnofpu(dc)) |
1478 | 1494 |
goto jmp_insn; |
1495 |
gen_op_clear_ieee_excp_and_FTT(); |
|
1479 | 1496 |
rs1 = GET_FIELD(insn, 13, 17); |
1480 | 1497 |
rs2 = GET_FIELD(insn, 27, 31); |
1481 | 1498 |
xop = GET_FIELD(insn, 18, 26); |
... | ... | |
1653 | 1670 |
gen_op_load_fpr_FT0(rs1); |
1654 | 1671 |
gen_op_load_fpr_FT1(rs2); |
1655 | 1672 |
#ifdef TARGET_SPARC64 |
1656 |
gen_fcmps[rd & 3](); |
|
1673 |
gen_fcmpes[rd & 3]();
|
|
1657 | 1674 |
#else |
1658 |
gen_op_fcmps(); /* XXX should trap if qNaN or sNaN */
|
|
1675 |
gen_op_fcmpes();
|
|
1659 | 1676 |
#endif |
1660 | 1677 |
break; |
1661 | 1678 |
case 0x56: /* fcmped, V9 %fcc */ |
1662 | 1679 |
gen_op_load_fpr_DT0(DFPREG(rs1)); |
1663 | 1680 |
gen_op_load_fpr_DT1(DFPREG(rs2)); |
1664 | 1681 |
#ifdef TARGET_SPARC64 |
1665 |
gen_fcmpd[rd & 3](); |
|
1682 |
gen_fcmped[rd & 3]();
|
|
1666 | 1683 |
#else |
1667 |
gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN */
|
|
1684 |
gen_op_fcmped();
|
|
1668 | 1685 |
#endif |
1669 | 1686 |
break; |
1670 | 1687 |
case 0x57: /* fcmpeq */ |
Also available in: Unified diff