Commit 417454b0322ab1eed03615fe563d770fa7e4c9f9
1 parent
c185970a
Full implementation of IEEE exceptions (Aurelien Jarno)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2625 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
154 additions
and
14 deletions
target-sparc/exec.h
@@ -61,6 +61,8 @@ void do_fsqrts(void); | @@ -61,6 +61,8 @@ void do_fsqrts(void); | ||
61 | void do_fsqrtd(void); | 61 | void do_fsqrtd(void); |
62 | void do_fcmps(void); | 62 | void do_fcmps(void); |
63 | void do_fcmpd(void); | 63 | void do_fcmpd(void); |
64 | +void do_fcmpes(void); | ||
65 | +void do_fcmped(void); | ||
64 | #ifdef TARGET_SPARC64 | 66 | #ifdef TARGET_SPARC64 |
65 | void do_fabsd(void); | 67 | void do_fabsd(void); |
66 | void do_fcmps_fcc1(void); | 68 | void do_fcmps_fcc1(void); |
@@ -69,6 +71,12 @@ void do_fcmps_fcc2(void); | @@ -69,6 +71,12 @@ void do_fcmps_fcc2(void); | ||
69 | void do_fcmpd_fcc2(void); | 71 | void do_fcmpd_fcc2(void); |
70 | void do_fcmps_fcc3(void); | 72 | void do_fcmps_fcc3(void); |
71 | void do_fcmpd_fcc3(void); | 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 | void do_popc(); | 80 | void do_popc(); |
73 | void do_wrpstate(); | 81 | void do_wrpstate(); |
74 | void do_done(); | 82 | void do_done(); |
@@ -79,6 +87,7 @@ void do_ldd_user(target_ulong addr); | @@ -79,6 +87,7 @@ void do_ldd_user(target_ulong addr); | ||
79 | void do_ldd_raw(target_ulong addr); | 87 | void do_ldd_raw(target_ulong addr); |
80 | void do_interrupt(int intno); | 88 | void do_interrupt(int intno); |
81 | void raise_exception(int tt); | 89 | void raise_exception(int tt); |
90 | +void check_ieee_exceptions(); | ||
82 | void memcpy32(target_ulong *dst, const target_ulong *src); | 91 | void memcpy32(target_ulong *dst, const target_ulong *src); |
83 | target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); | 92 | target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); |
84 | void dump_mmu(CPUState *env); | 93 | void dump_mmu(CPUState *env); |
target-sparc/op.c
@@ -1534,16 +1534,25 @@ void OPPROTO op_flush_T0(void) | @@ -1534,16 +1534,25 @@ void OPPROTO op_flush_T0(void) | ||
1534 | helper_flush(T0); | 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 | #define F_OP(name, p) void OPPROTO op_f##name##p(void) | 1542 | #define F_OP(name, p) void OPPROTO op_f##name##p(void) |
1538 | 1543 | ||
1539 | #define F_BINOP(name) \ | 1544 | #define F_BINOP(name) \ |
1540 | F_OP(name, s) \ | 1545 | F_OP(name, s) \ |
1541 | { \ | 1546 | { \ |
1547 | + set_float_exception_flags(0, &env->fp_status); \ | ||
1542 | FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \ | 1548 | FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \ |
1549 | + check_ieee_exceptions(); \ | ||
1543 | } \ | 1550 | } \ |
1544 | F_OP(name, d) \ | 1551 | F_OP(name, d) \ |
1545 | { \ | 1552 | { \ |
1553 | + set_float_exception_flags(0, &env->fp_status); \ | ||
1546 | DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \ | 1554 | DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \ |
1555 | + check_ieee_exceptions(); \ | ||
1547 | } | 1556 | } |
1548 | 1557 | ||
1549 | F_BINOP(add); | 1558 | F_BINOP(add); |
@@ -1554,9 +1563,11 @@ F_BINOP(div); | @@ -1554,9 +1563,11 @@ F_BINOP(div); | ||
1554 | 1563 | ||
1555 | void OPPROTO op_fsmuld(void) | 1564 | void OPPROTO op_fsmuld(void) |
1556 | { | 1565 | { |
1566 | + set_float_exception_flags(0, &env->fp_status); | ||
1557 | DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status), | 1567 | DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status), |
1558 | float32_to_float64(FT1, &env->fp_status), | 1568 | float32_to_float64(FT1, &env->fp_status), |
1559 | &env->fp_status); | 1569 | &env->fp_status); |
1570 | + check_ieee_exceptions(); | ||
1560 | } | 1571 | } |
1561 | 1572 | ||
1562 | #define F_HELPER(name) \ | 1573 | #define F_HELPER(name) \ |
@@ -1582,6 +1593,7 @@ F_OP(abs, s) | @@ -1582,6 +1593,7 @@ F_OP(abs, s) | ||
1582 | } | 1593 | } |
1583 | 1594 | ||
1584 | F_HELPER(cmp); | 1595 | F_HELPER(cmp); |
1596 | +F_HELPER(cmpe); | ||
1585 | 1597 | ||
1586 | #ifdef TARGET_SPARC64 | 1598 | #ifdef TARGET_SPARC64 |
1587 | F_OP(neg, d) | 1599 | F_OP(neg, d) |
@@ -1623,6 +1635,37 @@ void OPPROTO op_fcmpd_fcc3(void) | @@ -1623,6 +1635,37 @@ void OPPROTO op_fcmpd_fcc3(void) | ||
1623 | { | 1635 | { |
1624 | do_fcmpd_fcc3(); | 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 | #endif | 1669 | #endif |
1627 | 1670 | ||
1628 | /* Integer to float conversion. */ | 1671 | /* Integer to float conversion. */ |
@@ -1631,23 +1674,31 @@ F_HELPER(ito); | @@ -1631,23 +1674,31 @@ F_HELPER(ito); | ||
1631 | #else | 1674 | #else |
1632 | F_OP(ito, s) | 1675 | F_OP(ito, s) |
1633 | { | 1676 | { |
1677 | + set_float_exception_flags(0, &env->fp_status); | ||
1634 | FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); | 1678 | FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); |
1679 | + check_ieee_exceptions(); | ||
1635 | } | 1680 | } |
1636 | 1681 | ||
1637 | F_OP(ito, d) | 1682 | F_OP(ito, d) |
1638 | { | 1683 | { |
1684 | + set_float_exception_flags(0, &env->fp_status); | ||
1639 | DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status); | 1685 | DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status); |
1686 | + check_ieee_exceptions(); | ||
1640 | } | 1687 | } |
1641 | 1688 | ||
1642 | #ifdef TARGET_SPARC64 | 1689 | #ifdef TARGET_SPARC64 |
1643 | F_OP(xto, s) | 1690 | F_OP(xto, s) |
1644 | { | 1691 | { |
1692 | + set_float_exception_flags(0, &env->fp_status); | ||
1645 | FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status); | 1693 | FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status); |
1694 | + check_ieee_exceptions(); | ||
1646 | } | 1695 | } |
1647 | 1696 | ||
1648 | F_OP(xto, d) | 1697 | F_OP(xto, d) |
1649 | { | 1698 | { |
1699 | + set_float_exception_flags(0, &env->fp_status); | ||
1650 | DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status); | 1700 | DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status); |
1701 | + check_ieee_exceptions(); | ||
1651 | } | 1702 | } |
1652 | #endif | 1703 | #endif |
1653 | #endif | 1704 | #endif |
@@ -1656,34 +1707,46 @@ F_OP(xto, d) | @@ -1656,34 +1707,46 @@ F_OP(xto, d) | ||
1656 | /* floating point conversion */ | 1707 | /* floating point conversion */ |
1657 | void OPPROTO op_fdtos(void) | 1708 | void OPPROTO op_fdtos(void) |
1658 | { | 1709 | { |
1710 | + set_float_exception_flags(0, &env->fp_status); | ||
1659 | FT0 = float64_to_float32(DT1, &env->fp_status); | 1711 | FT0 = float64_to_float32(DT1, &env->fp_status); |
1712 | + check_ieee_exceptions(); | ||
1660 | } | 1713 | } |
1661 | 1714 | ||
1662 | void OPPROTO op_fstod(void) | 1715 | void OPPROTO op_fstod(void) |
1663 | { | 1716 | { |
1717 | + set_float_exception_flags(0, &env->fp_status); | ||
1664 | DT0 = float32_to_float64(FT1, &env->fp_status); | 1718 | DT0 = float32_to_float64(FT1, &env->fp_status); |
1719 | + check_ieee_exceptions(); | ||
1665 | } | 1720 | } |
1666 | 1721 | ||
1667 | /* Float to integer conversion. */ | 1722 | /* Float to integer conversion. */ |
1668 | void OPPROTO op_fstoi(void) | 1723 | void OPPROTO op_fstoi(void) |
1669 | { | 1724 | { |
1725 | + set_float_exception_flags(0, &env->fp_status); | ||
1670 | *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status); | 1726 | *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status); |
1727 | + check_ieee_exceptions(); | ||
1671 | } | 1728 | } |
1672 | 1729 | ||
1673 | void OPPROTO op_fdtoi(void) | 1730 | void OPPROTO op_fdtoi(void) |
1674 | { | 1731 | { |
1732 | + set_float_exception_flags(0, &env->fp_status); | ||
1675 | *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status); | 1733 | *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status); |
1734 | + check_ieee_exceptions(); | ||
1676 | } | 1735 | } |
1677 | 1736 | ||
1678 | #ifdef TARGET_SPARC64 | 1737 | #ifdef TARGET_SPARC64 |
1679 | void OPPROTO op_fstox(void) | 1738 | void OPPROTO op_fstox(void) |
1680 | { | 1739 | { |
1740 | + set_float_exception_flags(0, &env->fp_status); | ||
1681 | *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status); | 1741 | *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status); |
1742 | + check_ieee_exceptions(); | ||
1682 | } | 1743 | } |
1683 | 1744 | ||
1684 | void OPPROTO op_fdtox(void) | 1745 | void OPPROTO op_fdtox(void) |
1685 | { | 1746 | { |
1747 | + set_float_exception_flags(0, &env->fp_status); | ||
1686 | *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status); | 1748 | *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status); |
1749 | + check_ieee_exceptions(); | ||
1687 | } | 1750 | } |
1688 | 1751 | ||
1689 | void OPPROTO op_fmovs_cc(void) | 1752 | void OPPROTO op_fmovs_cc(void) |
target-sparc/op_helper.c
@@ -9,10 +9,43 @@ void raise_exception(int tt) | @@ -9,10 +9,43 @@ void raise_exception(int tt) | ||
9 | cpu_loop_exit(); | 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 | #ifdef USE_INT_TO_FLOAT_HELPERS | 43 | #ifdef USE_INT_TO_FLOAT_HELPERS |
13 | void do_fitos(void) | 44 | void do_fitos(void) |
14 | { | 45 | { |
46 | + set_float_exception_flags(0, &env->fp_status); | ||
15 | FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); | 47 | FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); |
48 | + check_ieee_exceptions(); | ||
16 | } | 49 | } |
17 | 50 | ||
18 | void do_fitod(void) | 51 | void do_fitod(void) |
@@ -35,23 +68,29 @@ void do_fabsd(void) | @@ -35,23 +68,29 @@ void do_fabsd(void) | ||
35 | 68 | ||
36 | void do_fsqrts(void) | 69 | void do_fsqrts(void) |
37 | { | 70 | { |
71 | + set_float_exception_flags(0, &env->fp_status); | ||
38 | FT0 = float32_sqrt(FT1, &env->fp_status); | 72 | FT0 = float32_sqrt(FT1, &env->fp_status); |
73 | + check_ieee_exceptions(); | ||
39 | } | 74 | } |
40 | 75 | ||
41 | void do_fsqrtd(void) | 76 | void do_fsqrtd(void) |
42 | { | 77 | { |
78 | + set_float_exception_flags(0, &env->fp_status); | ||
43 | DT0 = float64_sqrt(DT1, &env->fp_status); | 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 | void glue(do_, name) (void) \ | 84 | void glue(do_, name) (void) \ |
48 | { \ | 85 | { \ |
49 | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ | 86 | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
50 | switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \ | 87 | switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \ |
51 | case float_relation_unordered: \ | 88 | case float_relation_unordered: \ |
52 | T0 = (FSR_FCC1 | FSR_FCC0) << FS; \ | 89 | T0 = (FSR_FCC1 | FSR_FCC0) << FS; \ |
53 | - if (env->fsr & FSR_NVM) { \ | 90 | + if ((env->fsr & FSR_NVM) || TRAP) { \ |
54 | env->fsr |= T0; \ | 91 | env->fsr |= T0; \ |
92 | + env->fsr |= FSR_NVC; \ | ||
93 | + env->fsr |= FSR_FTT_IEEE_EXCP; \ | ||
55 | raise_exception(TT_FP_EXCP); \ | 94 | raise_exception(TT_FP_EXCP); \ |
56 | } else { \ | 95 | } else { \ |
57 | env->fsr |= FSR_NVA; \ | 96 | env->fsr |= FSR_NVA; \ |
@@ -70,18 +109,30 @@ void do_fsqrtd(void) | @@ -70,18 +109,30 @@ void do_fsqrtd(void) | ||
70 | env->fsr |= T0; \ | 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 | #ifdef TARGET_SPARC64 | 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 | #endif | 136 | #endif |
86 | 137 | ||
87 | #if defined(CONFIG_USER_ONLY) | 138 | #if defined(CONFIG_USER_ONLY) |
target-sparc/translate.c
@@ -943,6 +943,21 @@ static GenOpFunc * const gen_fcmpd[4] = { | @@ -943,6 +943,21 @@ static GenOpFunc * const gen_fcmpd[4] = { | ||
943 | gen_op_fcmpd_fcc2, | 943 | gen_op_fcmpd_fcc2, |
944 | gen_op_fcmpd_fcc3, | 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 | #endif | 961 | #endif |
947 | 962 | ||
948 | static int gen_trap_ifnofpu(DisasContext * dc) | 963 | static int gen_trap_ifnofpu(DisasContext * dc) |
@@ -1289,6 +1304,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -1289,6 +1304,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
1289 | } else if (xop == 0x34) { /* FPU Operations */ | 1304 | } else if (xop == 0x34) { /* FPU Operations */ |
1290 | if (gen_trap_ifnofpu(dc)) | 1305 | if (gen_trap_ifnofpu(dc)) |
1291 | goto jmp_insn; | 1306 | goto jmp_insn; |
1307 | + gen_op_clear_ieee_excp_and_FTT(); | ||
1292 | rs1 = GET_FIELD(insn, 13, 17); | 1308 | rs1 = GET_FIELD(insn, 13, 17); |
1293 | rs2 = GET_FIELD(insn, 27, 31); | 1309 | rs2 = GET_FIELD(insn, 27, 31); |
1294 | xop = GET_FIELD(insn, 18, 26); | 1310 | xop = GET_FIELD(insn, 18, 26); |
@@ -1476,6 +1492,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -1476,6 +1492,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
1476 | #endif | 1492 | #endif |
1477 | if (gen_trap_ifnofpu(dc)) | 1493 | if (gen_trap_ifnofpu(dc)) |
1478 | goto jmp_insn; | 1494 | goto jmp_insn; |
1495 | + gen_op_clear_ieee_excp_and_FTT(); | ||
1479 | rs1 = GET_FIELD(insn, 13, 17); | 1496 | rs1 = GET_FIELD(insn, 13, 17); |
1480 | rs2 = GET_FIELD(insn, 27, 31); | 1497 | rs2 = GET_FIELD(insn, 27, 31); |
1481 | xop = GET_FIELD(insn, 18, 26); | 1498 | xop = GET_FIELD(insn, 18, 26); |
@@ -1653,18 +1670,18 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -1653,18 +1670,18 @@ static void disas_sparc_insn(DisasContext * dc) | ||
1653 | gen_op_load_fpr_FT0(rs1); | 1670 | gen_op_load_fpr_FT0(rs1); |
1654 | gen_op_load_fpr_FT1(rs2); | 1671 | gen_op_load_fpr_FT1(rs2); |
1655 | #ifdef TARGET_SPARC64 | 1672 | #ifdef TARGET_SPARC64 |
1656 | - gen_fcmps[rd & 3](); | 1673 | + gen_fcmpes[rd & 3](); |
1657 | #else | 1674 | #else |
1658 | - gen_op_fcmps(); /* XXX should trap if qNaN or sNaN */ | 1675 | + gen_op_fcmpes(); |
1659 | #endif | 1676 | #endif |
1660 | break; | 1677 | break; |
1661 | case 0x56: /* fcmped, V9 %fcc */ | 1678 | case 0x56: /* fcmped, V9 %fcc */ |
1662 | gen_op_load_fpr_DT0(DFPREG(rs1)); | 1679 | gen_op_load_fpr_DT0(DFPREG(rs1)); |
1663 | gen_op_load_fpr_DT1(DFPREG(rs2)); | 1680 | gen_op_load_fpr_DT1(DFPREG(rs2)); |
1664 | #ifdef TARGET_SPARC64 | 1681 | #ifdef TARGET_SPARC64 |
1665 | - gen_fcmpd[rd & 3](); | 1682 | + gen_fcmped[rd & 3](); |
1666 | #else | 1683 | #else |
1667 | - gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN */ | 1684 | + gen_op_fcmped(); |
1668 | #endif | 1685 | #endif |
1669 | break; | 1686 | break; |
1670 | case 0x57: /* fcmpeq */ | 1687 | case 0x57: /* fcmpeq */ |