~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to src/emu/cpu/m68000/m68kfpu.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Emmanuel Kasper, Jordi Mallach
  • Date: 2012-06-05 20:02:23 UTC
  • mfrom: (0.3.1) (0.1.4)
  • Revision ID: package-import@ubuntu.com-20120605200223-gnlpogjrg6oqe9md
Tags: 0.146-1
[ Emmanuel Kasper ]
* New upstream release
* Drop patch to fix man pages section and patches to link with flac 
  and jpeg system lib: all this has been pushed upstream by Cesare Falco
* Add DM-Upload-Allowed: yes field.

[ Jordi Mallach ]
* Create a "gnu" TARGETOS stanza that defines NO_AFFINITY_NP.
* Stop setting TARGETOS to "unix" in d/rules. It should be autodetected,
  and set to the appropriate value.
* mame_manpage_section.patch: Change mame's manpage section to 6 (games),
  in the TH declaration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
#define FPCC_I                  0x02000000
6
6
#define FPCC_NAN                0x01000000
7
7
 
 
8
#define FPES_OE                 0x00002000
 
9
#define FPAE_IOP                0x00000080
 
10
 
8
11
#define DOUBLE_INFINITY                                 U64(0x7ff0000000000000)
9
12
#define DOUBLE_EXPONENT                                 U64(0x7ff0000000000000)
10
13
#define DOUBLE_MANTISSA                                 U64(0x000fffffffffffff)
1318
1321
                        m68k->remaining_cycles -= 109;
1319
1322
                        break;
1320
1323
                }
 
1324
                case 0x06:              // FLOGNP1
 
1325
                {
 
1326
                        REG_FP(m68k)[dst] = floatx80_flognp1 (source);
 
1327
                        SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
 
1328
                        m68k->remaining_cycles -= 594; // for MC68881
 
1329
                        break;
 
1330
                }
1321
1331
                case 0x0e:      // FSIN
1322
1332
                {
1323
1333
                        REG_FP(m68k)[dst] = source;
1334
1344
                        m68k->remaining_cycles -= 75;
1335
1345
                        break;
1336
1346
                }
 
1347
                case 0x14:              // FLOGN
 
1348
                {
 
1349
                        REG_FP(m68k)[dst] = floatx80_flogn (source);
 
1350
                        SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
 
1351
                        m68k->remaining_cycles -= 548; // for MC68881
 
1352
                        break;
 
1353
                }
 
1354
                case 0x15:              // FLOG10
 
1355
                {
 
1356
                        REG_FP(m68k)[dst] = floatx80_flog10 (source);
 
1357
                        SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
 
1358
                        m68k->remaining_cycles -= 604; // for MC68881
 
1359
                        break;
 
1360
                }
 
1361
                case 0x16:              // FLOG2
 
1362
                {
 
1363
                        REG_FP(m68k)[dst] = floatx80_flog2 (source);
 
1364
                        SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
 
1365
                        m68k->remaining_cycles -= 604; // for MC68881
 
1366
                        break;
 
1367
                }
1337
1368
                case 0x18:              // FABS
1338
1369
                {
1339
1370
                        REG_FP(m68k)[dst] = source;
1367
1398
                        REG_FP(m68k)[dst] = double_to_fx80((double)temp2);
1368
1399
                        SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1369
1400
                        m68k->remaining_cycles -= 6;
 
1401
                        break;
1370
1402
                }
1371
1403
                case 0x20:              // FDIV
1372
1404
                {
1390
1422
                }
1391
1423
                case 0x24:              // FSGLDIV
1392
1424
                {
1393
 
                        REG_FP(m68k)[dst] = floatx80_div(REG_FP(m68k)[dst], source);
 
1425
                        float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
 
1426
                        float32 b = floatx80_to_float32( source );
 
1427
                        REG_FP(m68k)[dst] = float32_to_floatx80( float32_div(a, b) );
1394
1428
                        m68k->remaining_cycles -= 43; //  // ? (value is from FDIV)
1395
1429
                        break;
1396
1430
                }
1403
1437
                }
1404
1438
                case 0x27:              // FSGLMUL
1405
1439
                {
1406
 
                        REG_FP(m68k)[dst] = floatx80_mul(REG_FP(m68k)[dst], source);
 
1440
                        float32 a = floatx80_to_float32( REG_FP(m68k)[dst] );
 
1441
                        float32 b = floatx80_to_float32( source );
 
1442
                        REG_FP(m68k)[dst] = float32_to_floatx80( float32_mul(a, b) );
1407
1443
                        SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
1408
1444
                        m68k->remaining_cycles -= 11; // ? (value is from FMUL)
1409
1445
                        break;
1471
1507
                }
1472
1508
                case 4:         // Word Integer
1473
1509
                {
1474
 
                        WRITE_EA_16(m68k, ea, (INT16)floatx80_to_int32(REG_FP(m68k)[src]));
 
1510
                        int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
 
1511
                        if (value > 0x7fff || value < -0x8000 )
 
1512
                        {
 
1513
                                REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
 
1514
                        }
 
1515
                        WRITE_EA_16(m68k, ea, (INT16)value);
1475
1516
                        break;
1476
1517
                }
1477
1518
                case 5:         // Double-precision Real
1485
1526
                }
1486
1527
                case 6:         // Byte Integer
1487
1528
                {
1488
 
                        WRITE_EA_8(m68k, ea, (INT8)floatx80_to_int32(REG_FP(m68k)[src]));
 
1529
                        int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
 
1530
                        if (value > 127 || value < -128)
 
1531
                        {
 
1532
                                REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
 
1533
                        }
 
1534
                        WRITE_EA_8(m68k, ea, (INT8) value);
1489
1535
                        break;
1490
1536
                }
1491
1537
                case 7:         // Packed-decimal Real with Dynamic K-factor
1547
1593
                }
1548
1594
        }
1549
1595
 
 
1596
#if 0
 
1597
        // FIXME: (2011-12-18 ost)
 
1598
        // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
 
1599
        // but:  with this code on Apollo the following programs in /systest/fptest will fail:
 
1600
        // 1. Single Precision Whetstone will return wrong results never the less
 
1601
        // 2. Vector Test will fault with 00040004: reference to illegal address
 
1602
 
 
1603
        if ((regsel & 4) && dir == 0)
 
1604
        {
 
1605
                int rnd = (REG_FPCR(m68k) >> 4) & 3;
 
1606
                int prec = (REG_FPCR(m68k) >> 6) & 3;
 
1607
 
 
1608
                logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", REG_FPCR(m68k), prec, rnd);
 
1609
 
 
1610
#ifdef FLOATX80
 
1611
                switch (prec)
 
1612
                {
 
1613
                case 0: // Extend (X)
 
1614
                        floatx80_rounding_precision = 80;
 
1615
                        break;
 
1616
                case 1: // Single (S)
 
1617
                        floatx80_rounding_precision = 32;
 
1618
                        break;
 
1619
                case 2: // Double (D)
 
1620
                        floatx80_rounding_precision = 64;
 
1621
                        break;
 
1622
                case 3: // Undefined
 
1623
                        floatx80_rounding_precision = 80;
 
1624
                        break;
 
1625
                }
 
1626
#endif
 
1627
 
 
1628
                switch (rnd)
 
1629
                {
 
1630
                case 0: // To Nearest (RN)
 
1631
                        float_rounding_mode = float_round_nearest_even;
 
1632
                        break;
 
1633
                case 1: // To Zero (RZ)
 
1634
                        float_rounding_mode = float_round_to_zero;
 
1635
                        break;
 
1636
                case 2: // To Minus Infinitiy (RM)
 
1637
                        float_rounding_mode = float_round_down;
 
1638
                        break;
 
1639
                case 3: // To Plus Infinitiy (RP)
 
1640
                        float_rounding_mode = float_round_up;
 
1641
                        break;
 
1642
                }
 
1643
        }
 
1644
#endif
 
1645
 
1550
1646
        m68k->remaining_cycles -= 10;
1551
1647
}
1552
1648
 
1779
1875
        }
1780
1876
}
1781
1877
 
1782
 
static void perform_fsave(m68ki_cpu_core *m68k, UINT32 addr, int inc)
 
1878
static int perform_fsave(m68ki_cpu_core *m68k, UINT32 addr, int inc)
1783
1879
{
 
1880
        if(m68k->cpu_type & CPU_TYPE_040)
 
1881
        {
 
1882
                if(inc)
 
1883
                {
 
1884
                        m68ki_write_32(m68k, addr, 0x41000000);
 
1885
                        return 4;
 
1886
                }
 
1887
                else
 
1888
                {
 
1889
                        m68ki_write_32(m68k, addr-4, 0x41000000);
 
1890
                        return -4;
 
1891
                }
 
1892
        }
 
1893
 
1784
1894
        if (inc)
1785
1895
        {
1786
1896
                // 68881 IDLE, version 0x1f
1791
1901
                m68ki_write_32(m68k, addr+16, 0);
1792
1902
                m68ki_write_32(m68k, addr+20, 0);
1793
1903
                m68ki_write_32(m68k, addr+24, 0x70000000);
 
1904
                return 7*4;
1794
1905
        }
1795
1906
        else
1796
1907
        {
1797
 
                m68ki_write_32(m68k, addr, 0x70000000);
1798
 
                m68ki_write_32(m68k, addr-4, 0);
 
1908
                m68ki_write_32(m68k, addr-4, 0x70000000);
1799
1909
                m68ki_write_32(m68k, addr-8, 0);
1800
1910
                m68ki_write_32(m68k, addr-12, 0);
1801
1911
                m68ki_write_32(m68k, addr-16, 0);
1802
1912
                m68ki_write_32(m68k, addr-20, 0);
1803
 
                m68ki_write_32(m68k, addr-24, 0x1f180000);
 
1913
                m68ki_write_32(m68k, addr-24, 0);
 
1914
                m68ki_write_32(m68k, addr-28, 0x1f180000);
 
1915
                return -7*4;
1804
1916
        }
1805
1917
}
1806
1918
 
1832
1944
        else
1833
1945
        {
1834
1946
                // we normally generate an IDLE frame
 
1947
                int delta = perform_fsave(m68k, addr, inc);
1835
1948
                if(reg != -1)
1836
 
                        REG_A(m68k)[reg] += inc ? 6*4 : -6*4;
1837
 
                perform_fsave(m68k, addr, inc);
 
1949
                        REG_A(m68k)[reg] += delta;
1838
1950
        }
1839
1951
}
1840
1952
 
1841
1953
static void m68040_do_frestore(m68ki_cpu_core *m68k, UINT32 addr, int reg)
1842
1954
{
 
1955
        bool m40 = m68k->cpu_type & CPU_TYPE_040;
1843
1956
        UINT32 temp = m68ki_read_32(m68k, addr);
1844
1957
 
1845
1958
        // check for NULL frame
1851
1964
                if (reg != -1)
1852
1965
                {
1853
1966
                        // how about an IDLE frame?
1854
 
                        if ((temp & 0x00ff0000) == 0x00180000)
1855
 
                        {
1856
 
                                REG_A(m68k)[reg] += 6*4;
 
1967
                        if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
 
1968
                        {
 
1969
                                REG_A(m68k)[reg] += 7*4;
 
1970
                        }
 
1971
                        else if (m40 && ((temp & 0xffff0000) == 0x41000000))
 
1972
                        {
 
1973
                                REG_A(m68k)[reg] += 4;
1857
1974
                        } // check UNIMP
1858
1975
                        else if ((temp & 0x00ff0000) == 0x00380000)
1859
1976
                        {
1901
2018
 
1902
2019
                        case 5: // (D16, An)
1903
2020
                                addr = EA_AY_DI_16(m68k);
1904
 
                                m68040_do_fsave(m68k, addr, -1, 0);
 
2021
                                m68040_do_fsave(m68k, addr, -1, 1);
1905
2022
                                break;
1906
2023
 
1907
2024
                        case 7: //