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