Revision 6c01bf6c

b/target-ppc/op_helper.c
563 563
    return ((u.ll >> 52) & 0x7FF) == 0;
564 564
}
565 565

  
566
#ifdef CONFIG_SOFTFLOAT
567
static always_inline int isnormal (float64 d)
568
{
569
    CPU_DoubleU u;
570

  
571
    u.d = d;
572

  
573
    uint32_t exp = (u.ll >> 52) & 0x7FF;
574
    return ((0 < exp) && (exp < 0x7FF));
575
}
576
#endif
577

  
578 566
uint32_t helper_compute_fprf (uint64_t arg, uint32_t set_fprf)
579 567
{
580 568
    CPU_DoubleU farg;
......
1528 1516
    } else if (unlikely(float64_is_zero(farg.d))) {
1529 1517
        /* Zero reciprocal */
1530 1518
        farg.ll = float_zero_divide_excp(fone.d, farg.d);
1531
    } else if (likely(isnormal(farg.d))) {
1532
        farg.d = float64_div(fone.d, farg.d, &env->fp_status);
1533 1519
    } else {
1534
        if (farg.ll == 0x8000000000000000ULL) {
1535
            farg.ll = 0xFFF0000000000000ULL;
1536
        } else if (farg.ll == 0x0000000000000000ULL) {
1537
            farg.ll = 0x7FF0000000000000ULL;
1538
        } else if (float64_is_nan(farg.d)) {
1539
            farg.ll = 0x7FF8000000000000ULL;
1540
        } else if (float64_is_neg(farg.d)) {
1541
            farg.ll = 0x8000000000000000ULL;
1542
        } else {
1543
            farg.ll = 0x0000000000000000ULL;
1544
        }
1520
        farg.d = float64_div(fone.d, farg.d, &env->fp_status);
1545 1521
    }
1546 1522
    return farg.d;
1547 1523
}
......
1550 1526
uint64_t helper_fres (uint64_t arg)
1551 1527
{
1552 1528
    CPU_DoubleU fone, farg;
1529
    float32 f32;
1553 1530
    fone.ll = 0x3FF0000000000000ULL; /* 1.0 */
1554 1531
    farg.ll = arg;
1555 1532

  
......
1559 1536
    } else if (unlikely(float64_is_zero(farg.d))) {
1560 1537
        /* Zero reciprocal */
1561 1538
        farg.ll = float_zero_divide_excp(fone.d, farg.d);
1562
    } else if (likely(isnormal(farg.d))) {
1563
#if USE_PRECISE_EMULATION
1564
        farg.d = float64_div(fone.d, farg.d, &env->fp_status);
1565
        farg.d = float64_to_float32(farg.d, &env->fp_status);
1566
#else
1567
        farg.d = float32_div(fone.d, farg.d, &env->fp_status);
1568
#endif
1569 1539
    } else {
1570
        if (farg.ll == 0x8000000000000000ULL) {
1571
            farg.ll = 0xFFF0000000000000ULL;
1572
        } else if (farg.ll == 0x0000000000000000ULL) {
1573
            farg.ll = 0x7FF0000000000000ULL;
1574
        } else if (float64_is_nan(farg.d)) {
1575
            farg.ll = 0x7FF8000000000000ULL;
1576
        } else if (float64_is_neg(farg.d)) {
1577
            farg.ll = 0x8000000000000000ULL;
1578
        } else {
1579
            farg.ll = 0x0000000000000000ULL;
1580
        }
1540
        farg.d = float64_div(fone.d, farg.d, &env->fp_status);
1541
        f32 = float64_to_float32(farg.d, &env->fp_status);
1542
        farg.d = float32_to_float64(f32, &env->fp_status);
1581 1543
    }
1582 1544
    return farg.ll;
1583 1545
}
......
1586 1548
uint64_t helper_frsqrte (uint64_t arg)
1587 1549
{
1588 1550
    CPU_DoubleU fone, farg;
1551
    float32 f32;
1589 1552
    fone.ll = 0x3FF0000000000000ULL; /* 1.0 */
1590 1553
    farg.ll = arg;
1591 1554

  
......
1595 1558
    } else if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d))) {
1596 1559
        /* Reciprocal square root of a negative nonzero number */
1597 1560
        farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSQRT);
1598
    } else if (likely(isnormal(farg.d))) {
1599
        farg.d = float64_sqrt(farg.d, &env->fp_status);
1600
        farg.d = float32_div(fone.d, farg.d, &env->fp_status);
1601 1561
    } else {
1602
        if (farg.ll == 0x8000000000000000ULL) {
1603
            farg.ll = 0xFFF0000000000000ULL;
1604
        } else if (farg.ll == 0x0000000000000000ULL) {
1605
            farg.ll = 0x7FF0000000000000ULL;
1606
        } else if (float64_is_nan(farg.d)) {
1607
            farg.ll |= 0x000FFFFFFFFFFFFFULL;
1608
        } else if (float64_is_neg(farg.d)) {
1609
            farg.ll = 0x7FF8000000000000ULL;
1610
        } else {
1611
            farg.ll = 0x0000000000000000ULL;
1612
        }
1562
        farg.d = float64_sqrt(farg.d, &env->fp_status);
1563
        farg.d = float64_div(fone.d, farg.d, &env->fp_status);
1564
        f32 = float64_to_float32(farg.d, &env->fp_status);
1565
        farg.d = float32_to_float64(f32, &env->fp_status);
1613 1566
    }
1614 1567
    return farg.ll;
1615 1568
}

Also available in: Unified diff