Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 160627 | Differences between
and this patch

Collapse All | Expand All

(-)qemu-1/qemu/cpu-all.h (+6 lines)
Lines 369-375 Link Here
369
369
370
static inline void stq_le_p(void *ptr, uint64_t v)
370
static inline void stq_le_p(void *ptr, uint64_t v)
371
{
371
{
372
#if defined(__i386__) && __GNUC__ >= 4
373
    const union { uint64_t v; uint32_t p[2]; } x = { .v = v };
374
    ((uint32_t *)ptr)[0] = x.p[0];
375
    ((uint32_t *)ptr)[1] = x.p[1];
376
#else
372
    *(uint64_t *)ptr = v;
377
    *(uint64_t *)ptr = v;
378
#endif
373
}
379
}
374
380
375
/* float access */
381
/* float access */
(-)qemu-1/qemu/dyngen.c (-22 / +758 lines)
Lines 32-37 Link Here
32
32
33
#include "config-host.h"
33
#include "config-host.h"
34
34
35
//#define DEBUG_OP
36
35
/* NOTE: we test CONFIG_WIN32 instead of _WIN32 to enabled cross
37
/* NOTE: we test CONFIG_WIN32 instead of _WIN32 to enabled cross
36
   compilation */
38
   compilation */
37
#if defined(CONFIG_WIN32)
39
#if defined(CONFIG_WIN32)
Lines 1429-1434 Link Here
1429
#endif
1431
#endif
1430
1432
1431
1433
1434
#if defined(HOST_I386) || defined(HOST_X86_64)
1435
1436
/* This byte is the first byte of an instruction.  */
1437
#define FLAG_INSN     (1 << 0)
1438
/* This byte has been processed as part of an instruction.  */
1439
#define FLAG_SCANNED  (1 << 1)
1440
/* This instruction is a return instruction.  Gcc cometimes generates prefix
1441
   bytes, so may be more than one byte long.  */
1442
#define FLAG_RET      (1 << 2)
1443
/* This is either the target of a jump, or the preceeding instruction uses
1444
   a pc-relative offset.  */
1445
#define FLAG_TARGET   (1 << 3)
1446
/* This is a magic instruction that needs fixing up.  */
1447
#define FLAG_EXIT     (1 << 4)
1448
/* This instruction clobbers the stack pointer.  */
1449
/* XXX only supports push, pop, add/sub $imm,%esp  */
1450
#define FLAG_STACK    (1 << 5)
1451
#define MAX_EXITS     5
1452
1453
static void
1454
bad_opcode(const char *name, uint32_t op)
1455
{
1456
    error("Unsupported opcode %0*x in %s", (op > 0xff) ? 4 : 2, op, name);
1457
}
1458
1459
/* Mark len bytes as scanned,  Returns insn_size + len.  Reports an error
1460
   if these bytes have already been scanned.  */
1461
static int
1462
eat_bytes(const char *name, char *flags, int insn, int insn_size, int len)
1463
{
1464
    while (len > 0) {
1465
        /* This should never occur in sane code.  */
1466
        if (flags[insn + insn_size] & FLAG_SCANNED)
1467
            error ("Overlapping instructions in %s", name);
1468
        flags[insn + insn_size] |= FLAG_SCANNED;
1469
        insn_size++;
1470
        len--;
1471
    }
1472
    return insn_size;
1473
}
1474
1475
static void
1476
trace_i386_insn (const char *name, uint8_t *start_p, char *flags, int insn,
1477
                 int len)
1478
{
1479
    uint8_t *ptr;
1480
    uint8_t op;
1481
    int modrm;
1482
    int is_prefix;
1483
    int op_size;
1484
    int addr_size;
1485
    int insn_size;
1486
    int is_ret;
1487
    int is_condjmp;
1488
    int is_jmp;
1489
    int is_exit;
1490
    int is_pcrel;
1491
    int is_stack;
1492
    int immed;
1493
    int seen_rexw;
1494
    int32_t disp;
1495
1496
    ptr = start_p + insn;
1497
    /* nonzero if this insn has a ModR/M byte.  */
1498
    modrm = 1;
1499
    /* The size of the immediate value in this instruction.  */
1500
    immed = 0;
1501
    /* The operand size.  */
1502
    op_size = 4;
1503
    /* The address size */
1504
    addr_size = 4;
1505
    /* The total length of this instruction.  */
1506
    insn_size = 0;
1507
    is_prefix = 1;
1508
    is_ret = 0;
1509
    is_condjmp = 0;
1510
    is_jmp = 0;
1511
    is_exit = 0;
1512
    seen_rexw = 0;
1513
    is_pcrel = 0;
1514
    is_stack = 0;
1515
1516
    while (is_prefix) {
1517
        op = ptr[insn_size];
1518
        insn_size = eat_bytes(name, flags, insn, insn_size, 1);
1519
        is_prefix = 0;
1520
        switch (op >> 4) {
1521
        case 0:
1522
        case 1:
1523
        case 2:
1524
        case 3:
1525
            if (op == 0x0f) {
1526
                /* two-byte opcode.  */
1527
                op = ptr[insn_size];
1528
                insn_size = eat_bytes(name, flags, insn, insn_size, 1);
1529
                switch (op >> 4) {
1530
                case 0:
1531
                    if ((op & 0xf) > 3)
1532
                      modrm = 0;
1533
                    break;
1534
                case 1: /* vector move or prefetch */
1535
                case 2: /* various moves and vector compares.  */
1536
                case 4: /* cmov */
1537
                case 5: /* vector instructions */
1538
                case 6:
1539
                case 13:
1540
                case 14:
1541
                case 15:
1542
                    break;
1543
                case 7: /* mmx */
1544
                    if (op & 0x77) /* emms */
1545
                      modrm = 0;
1546
                    break;
1547
                case 3: /* wrmsr, rdtsc, rdmsr, rdpmc, sysenter, sysexit */
1548
                    modrm = 0;
1549
                    break;
1550
                case 8: /* long conditional jump */
1551
                    is_condjmp = 1;
1552
                    immed = op_size;
1553
                    modrm = 0;
1554
                    break;
1555
                case 9: /* setcc */
1556
                    break;
1557
                case 10:
1558
                    switch (op & 0x7) {
1559
                    case 0: /* push fs/gs */
1560
                    case 1: /* pop fs/gs */
1561
                        is_stack = 1;
1562
                    case 2: /* cpuid/rsm */
1563
                        modrm = 0;
1564
                        break;
1565
                    case 4: /* shld/shrd immediate */
1566
                        immed = 1;
1567
                        break;
1568
                    default: /* Normal instructions with a ModR/M byte.  */
1569
                        break;
1570
                    }
1571
                    break;
1572
                case 11:
1573
                    switch (op & 0xf) {
1574
                    case 10: /* bt, bts, btr, btc */
1575
                        immed = 1;
1576
                        break;
1577
                    default:
1578
                        /* cmpxchg, lss, btr, lfs, lgs, movzx, btc, bsf, bsr
1579
                           undefined, and movsx */
1580
                        break;
1581
                    }
1582
                    break;
1583
                case 12:
1584
                    if (op & 8) {
1585
                        /* bswap */
1586
                        modrm = 0;
1587
                    } else {
1588
                        switch (op & 0x7) {
1589
                        case 2:
1590
                        case 4:
1591
                        case 5:
1592
                        case 6:
1593
                            immed = 1;
1594
                            break;
1595
                        default:
1596
                            break;
1597
                        }
1598
                    }
1599
                    break;
1600
                }
1601
            } else if ((op & 0x07) <= 0x3) {
1602
                /* General arithmentic ax.  */
1603
            } else if ((op & 0x07) <= 0x5) {
1604
                /* General arithmetic ax, immediate.  */
1605
                if (op & 0x01)
1606
                    immed = op_size;
1607
                else
1608
                    immed = 1;
1609
                modrm = 0;
1610
            } else if ((op & 0x23) == 0x22) {
1611
                /* Segment prefix.  */
1612
                is_prefix = 1;
1613
            } else {
1614
                /* Segment register push/pop or DAA/AAA/DAS/AAS.  */
1615
                modrm = 0;
1616
            }
1617
            break;
1618
1619
#if defined(HOST_X86_64)
1620
        case 4: /* rex prefix.  */
1621
            is_prefix = 1;
1622
            /* The address/operand size is actually 64-bit, but the immediate
1623
               values in the instruction are still 32-bit.  */
1624
            op_size = 4;
1625
            addr_size = 4;
1626
            if (op & 8)
1627
                seen_rexw = 1;
1628
            break;
1629
#else
1630
        case 4: /* inc/dec register.  */
1631
#endif
1632
        case 5: /* push/pop general register.  */
1633
            modrm = 0;
1634
            is_stack = 1;
1635
            break;
1636
1637
        case 6:
1638
            switch (op & 0x0f) {
1639
            case 0: /* pusha */
1640
            case 1: /* popa */
1641
                modrm = 0;
1642
                is_stack = 1;
1643
                break;
1644
            case 2: /* bound */
1645
            case 3: /* arpl */
1646
                break;
1647
            case 4: /* FS */
1648
            case 5: /* GS */
1649
                is_prefix = 1;
1650
                break;
1651
            case 6: /* opcode size prefix.  */
1652
                op_size = 2;
1653
                is_prefix = 1;
1654
                break;
1655
            case 7: /* Address size prefix.  */
1656
                addr_size = 2;
1657
                is_prefix = 1;
1658
                break;
1659
            case 8: /* push immediate */
1660
                immed = op_size;
1661
                modrm = 0;
1662
                is_stack = 1;
1663
                break;
1664
            case 10: /* push 8-bit immediate */
1665
                immed = 1;
1666
                modrm = 0;
1667
                is_stack = 1;
1668
                break;
1669
            case 9: /* imul immediate */
1670
                immed = op_size;
1671
                break;
1672
            case 11: /* imul 8-bit immediate */
1673
                immed = 1;
1674
                break;
1675
            case 12: /* insb */
1676
            case 13: /* insw */
1677
            case 14: /* outsb */
1678
            case 15: /* outsw */
1679
                modrm = 0;
1680
                break;
1681
            }
1682
            break;
1683
1684
        case 7: /* Short conditional jump.  */
1685
            is_condjmp = 1;
1686
            immed = 1;
1687
            modrm = 0;
1688
            break;
1689
          
1690
        case 8:
1691
            if ((op & 0xf) <= 3) {
1692
                /* arithmetic immediate.  */
1693
                if ((op & 3) == 1)
1694
                    immed = op_size;
1695
                else
1696
                    immed = 1;
1697
                if (op == 0x81 || op == 0x83) {
1698
                    /* add, sub */
1699
                    op = ptr[insn_size];
1700
                    switch ((op >> 3) & 7) {
1701
                    case 0:
1702
                    case 5:
1703
                        is_stack = (op & 7) == 4;
1704
                        break;
1705
                    }
1706
                }
1707
            }
1708
            else if ((op & 0xf) == 0xf) {
1709
                /* pop general.  */
1710
                is_stack = 1;
1711
            }
1712
            /* else test, xchg, mov, lea.  */
1713
            break;
1714
1715
        case 9:
1716
            /* Various single-byte opcodes with no modrm byte.  */
1717
            modrm = 0;
1718
            if (op == 10) {
1719
                /* Call */
1720
                immed = 4;
1721
            }
1722
            break;
1723
1724
        case 10:
1725
            switch ((op & 0xe) >> 1) {
1726
            case 0: /* mov absoliute immediate.  */
1727
            case 1:
1728
                if (seen_rexw)
1729
                    immed = 8;
1730
                else
1731
                    immed = addr_size;
1732
                break;
1733
            case 4: /* test immediate.  */
1734
                if (op & 1)
1735
                    immed = op_size;
1736
                else
1737
                    immed = 1;
1738
                break;
1739
            default: /* Various string ops.  */
1740
                break;
1741
            }
1742
            modrm = 0;
1743
            break;
1744
1745
        case 11: /* move immediate to register */
1746
            if (op & 8) {
1747
                if (seen_rexw)
1748
                    immed = 8;
1749
                else
1750
                    immed = op_size;
1751
            } else {
1752
                immed = 1;
1753
            }
1754
            modrm = 0;
1755
            break;
1756
1757
          case 12:
1758
            switch (op & 0xf) {
1759
            case 0: /* shift immediate */
1760
            case 1:
1761
                immed = 1;
1762
                break;
1763
            case 2: /* ret immediate */
1764
                immed = 2;
1765
                modrm = 0;
1766
                bad_opcode(name, op);
1767
                break;
1768
            case 3: /* ret */
1769
                modrm = 0;
1770
                is_ret = 1;
1771
            case 4: /* les */
1772
            case 5: /* lds */
1773
                break;
1774
            case 6: /* mov immediate byte */
1775
                immed = 1;
1776
                break;
1777
            case 7: /* mov immediate */
1778
                immed = op_size;
1779
                break;
1780
            case 8: /* enter */
1781
                /* TODO: Is this right?  */
1782
                immed = 3;
1783
                modrm = 0;
1784
                break;
1785
            case 10: /* retf immediate */
1786
                immed = 2;
1787
                modrm = 0;
1788
                bad_opcode(name, op);
1789
                break;
1790
            case 13: /* int */
1791
                immed = 1;
1792
                modrm = 0;
1793
                break;
1794
            case 11: /* retf */
1795
            case 15: /* iret */
1796
                modrm = 0;
1797
                bad_opcode(name, op);
1798
                break;
1799
            default: /* leave, int3 or into */
1800
                modrm = 0;
1801
                break;
1802
            }
1803
            break;
1804
1805
        case 13:
1806
            if ((op & 0xf) >= 8) {
1807
                /* Coprocessor escape.  For our purposes this is just a normal
1808
                   instruction with a ModR/M byte.  */
1809
            } else if ((op & 0xf) >= 4) {
1810
                /* AAM, AAD or XLAT */
1811
                modrm = 0;
1812
            }
1813
            /* else shift instruction */
1814
            break;
1815
1816
        case 14:
1817
            switch ((op & 0xc) >> 2) {
1818
            case 0: /* loop or jcxz */
1819
                is_condjmp = 1;
1820
                immed = 1;
1821
                break;
1822
            case 1: /* in/out immed */
1823
                immed = 1;
1824
                break;
1825
            case 2: /* call or jmp */
1826
                switch (op & 3) {
1827
                case 0: /* call */
1828
                    immed = op_size;
1829
                    break;
1830
                case 1: /* long jump */
1831
                    immed = 4;
1832
                    is_jmp = 1;
1833
                    break;
1834
                case 2: /* far jmp */
1835
                    bad_opcode(name, op);
1836
                    break;
1837
                case 3: /* short jmp */
1838
                    immed = 1;
1839
                    is_jmp = 1;
1840
                    break;
1841
                }
1842
                break;
1843
            case 3: /* in/out register */
1844
                break;
1845
            }
1846
            modrm = 0;
1847
            break;
1848
1849
        case 15:
1850
            switch ((op & 0xe) >> 1) {
1851
            case 0:
1852
            case 1:
1853
                is_prefix = 1;
1854
                break;
1855
            case 2:
1856
            case 4:
1857
            case 5:
1858
            case 6:
1859
                modrm = 0;
1860
                /* Some privileged insns are used as markers.  */
1861
                switch (op) {
1862
                case 0xf4: /* hlt: Exit translation block.  */
1863
                    is_exit = 1;
1864
                    break;
1865
                case 0xfa: /* cli: Jump to label.  */
1866
                    is_exit = 1;
1867
                    immed = 4;
1868
                    break;
1869
                case 0xfb: /* sti: TB patch jump.  */
1870
                    /* Mark the insn for patching, but continue sscanning.  */
1871
                    flags[insn] |= FLAG_EXIT;
1872
                    immed = 4;
1873
                    break;
1874
                }
1875
                break;
1876
            case 3: /* unary grp3 */
1877
                if ((ptr[insn_size] & 0x38) == 0) {
1878
                    if (op == 0xf7)
1879
                        immed = op_size;
1880
                    else
1881
                        immed = 1; /* test immediate */
1882
                }
1883
                break;
1884
            case 7: /* inc/dec grp4/5 */
1885
                /* TODO: This includes indirect jumps.  We should fail if we
1886
                   encounter one of these. */
1887
                break;
1888
            }
1889
            break;
1890
        }
1891
    }
1892
1893
    if (modrm) {
1894
        if (addr_size != 4)
1895
            error("16-bit addressing mode used in %s", name);
1896
1897
        disp = 0;
1898
        modrm = ptr[insn_size];
1899
        insn_size = eat_bytes(name, flags, insn, insn_size, 1);
1900
        modrm &= 0xc7;
1901
        switch ((modrm & 0xc0) >> 6) {
1902
        case 0:
1903
            if (modrm == 5)
1904
              disp = 4;
1905
            break;
1906
        case 1:
1907
            disp = 1;
1908
            break;
1909
        case 2:
1910
            disp = 4;
1911
            break;
1912
        }
1913
        if ((modrm & 0xc0) != 0xc0 && (modrm & 0x7) == 4) {
1914
            /* SIB byte */
1915
            if (modrm == 4 && (ptr[insn_size] & 0x7) == 5) {
1916
                disp = 4;
1917
                is_pcrel = 1;
1918
            }
1919
            insn_size = eat_bytes(name, flags, insn, insn_size, 1);
1920
        }
1921
        insn_size = eat_bytes(name, flags, insn, insn_size, disp);
1922
    }
1923
    insn_size = eat_bytes(name, flags, insn, insn_size, immed);
1924
    if (is_condjmp || is_jmp) {
1925
        if (immed == 1) {
1926
            disp = (int8_t)*(ptr + insn_size - 1);
1927
        } else {
1928
            disp = (((int32_t)*(ptr + insn_size - 1)) << 24)
1929
                   | (((int32_t)*(ptr + insn_size - 2)) << 16)
1930
                   | (((int32_t)*(ptr + insn_size - 3)) << 8)
1931
                   | *(ptr + insn_size - 4);
1932
        }
1933
        disp += insn_size;
1934
        /* Jumps to external symbols point to the address of the offset
1935
           before relocation.  */
1936
        /* ??? These are probably a tailcall.  We could fix them up by
1937
           replacing them with jmp to EOB + call, but it's easier to just
1938
           prevent the compiler generating them.  */
1939
        if (disp == 1)
1940
            error("Unconditional jump (sibcall?) in %s", name);
1941
        disp += insn;
1942
        if (disp < 0 || disp > len)
1943
            error("Jump outside instruction in %s", name);
1944
1945
        if ((flags[disp] & (FLAG_INSN | FLAG_SCANNED)) == FLAG_SCANNED)
1946
            error("Overlapping instructions in %s", name);
1947
1948
        flags[disp] |= (FLAG_INSN | FLAG_TARGET);
1949
        is_pcrel = 1; 
1950
    }
1951
    if (is_pcrel) {
1952
        /* Mark the following insn as a jump target.  This will stop
1953
           this instruction being moved.  */
1954
        flags[insn + insn_size] |= FLAG_TARGET;
1955
    }
1956
    if (is_ret)
1957
      flags[insn] |= FLAG_RET;
1958
1959
    if (is_exit)
1960
      flags[insn] |= FLAG_EXIT;
1961
1962
    if (is_stack)
1963
      flags[insn] |= FLAG_STACK;
1964
1965
    if (!(is_jmp || is_ret || is_exit))
1966
      flags[insn + insn_size] |= FLAG_INSN;
1967
}
1968
1969
/* Scan a function body.  Returns the position of the return sequence.
1970
   Sets *patch_bytes to the number of bytes that need to be copied from that
1971
   location.  If no patching is required (ie. the return is the last insn)
1972
   *patch_bytes will be set to -1.  *plen is the number of code bytes to copy.
1973
 */
1974
static int trace_i386_op(const char * name, uint8_t *start_p, int *plen,
1975
                         int *patch_bytes, int *exit_addrs)
1976
{
1977
    char *flags;
1978
    int more;
1979
    int insn;
1980
    int retpos;
1981
    int bytes;
1982
    int num_exits;
1983
    int len;
1984
    int last_insn;
1985
    int stack_clobbered;
1986
1987
    len = *plen;
1988
    flags = malloc(len + 1);
1989
    memset(flags, 0, len + 1);
1990
    flags[0] |= FLAG_INSN;
1991
    more = 1;
1992
    while (more) {
1993
        more = 0;
1994
        for (insn = 0; insn < len; insn++) {
1995
            if ((flags[insn] & (FLAG_INSN | FLAG_SCANNED)) == FLAG_INSN) {
1996
                trace_i386_insn(name, start_p, flags, insn, len);
1997
                more = 1;
1998
            }
1999
        }
2000
    }
2001
2002
    /* Strip any unused code at the end of the function.  */
2003
    while (len > 0 && flags[len - 1] == 0)
2004
      len--;
2005
2006
    retpos = -1;
2007
    num_exits = 0;
2008
    last_insn = 0;
2009
    stack_clobbered = 0;
2010
    for (insn = 0; insn < len; insn++) {
2011
        if (flags[insn] & FLAG_RET) {
2012
            /* ??? In theory it should be possible to handle multiple return
2013
               points.  In practice it's not worth the effort.  */
2014
            if (retpos != -1)
2015
                error("Multiple return instructions in %s", name);
2016
            retpos = insn;
2017
        }
2018
        if (flags[insn] & FLAG_EXIT) {
2019
            if (stack_clobbered)
2020
                error("Stack clobbered in %s", name);
2021
            if (num_exits == MAX_EXITS)
2022
                error("Too many block exits in %s", name);
2023
            exit_addrs[num_exits] = insn;
2024
            num_exits++;
2025
        }
2026
        if (flags[insn] & FLAG_INSN)
2027
            last_insn = insn;
2028
        if (flags[insn] & FLAG_STACK)
2029
            stack_clobbered = 1;
2030
    }
2031
2032
    exit_addrs[num_exits] = -1;
2033
    if (retpos == -1) {
2034
        if (num_exits == 0) {
2035
            error ("No return instruction found in %s", name);
2036
        } else {
2037
            retpos = len;
2038
            last_insn = len;
2039
        }
2040
    }
2041
    
2042
    /* If the return instruction is the last instruction we can just 
2043
       remove it.  */
2044
    if (retpos == last_insn)
2045
        *patch_bytes = -1;
2046
    else
2047
        *patch_bytes = 0;
2048
2049
    /* Back up over any nop instructions.  */
2050
    while (retpos > 0
2051
           && (flags[retpos] & FLAG_TARGET) == 0
2052
           && (flags[retpos - 1] & FLAG_INSN) != 0
2053
           && start_p[retpos - 1] == 0x90) {
2054
        retpos--;
2055
    }
2056
2057
    if (*patch_bytes == -1) {
2058
        *plen = retpos;
2059
        free (flags);
2060
        return retpos;
2061
    }
2062
    *plen = len;
2063
2064
    /* The ret is in the middle of the function.  Find four more bytes that
2065
       so the ret can be replaced by a jmp. */
2066
    /* ??? Use a short jump where possible. */
2067
    bytes = 4;
2068
    insn = retpos + 1;
2069
    /* We can clobber everything up to the next jump target.  */
2070
    while (insn < len && bytes > 0 && (flags[insn] & FLAG_TARGET) == 0) {
2071
        insn++;
2072
        bytes--;
2073
    }
2074
    if (bytes > 0) {
2075
        /* ???: Strip out nop blocks.  */
2076
        /* We can't do the replacement without clobbering anything important.
2077
           Copy preceeding instructions(s) to give us some space.  */
2078
        while (retpos > 0) {
2079
            /* If this byte is the target of a jmp we can't move it.  */
2080
            if (flags[retpos] & FLAG_TARGET)
2081
                break;
2082
2083
            (*patch_bytes)++;
2084
            bytes--;
2085
            retpos--;
2086
2087
            /* Break out of the loop if we have enough space and this is either 
2088
               the first byte of an instruction or a pad byte.  */
2089
            if ((flags[retpos] & (FLAG_INSN | FLAG_SCANNED)) != FLAG_SCANNED
2090
                && bytes <= 0) {
2091
                break;
2092
            }
2093
        }
2094
    }
2095
2096
    if (bytes > 0)
2097
        error("Unable to replace ret with jmp in %s\n", name);
2098
2099
    free(flags);
2100
    return retpos;
2101
}
2102
2103
#endif
2104
1432
#define MAX_ARGS 3
2105
#define MAX_ARGS 3
1433
2106
1434
/* generate op code */
2107
/* generate op code */
Lines 1442-1447 Link Here
1442
    uint8_t args_present[MAX_ARGS];
2115
    uint8_t args_present[MAX_ARGS];
1443
    const char *sym_name, *p;
2116
    const char *sym_name, *p;
1444
    EXE_RELOC *rel;
2117
    EXE_RELOC *rel;
2118
#if defined(HOST_I386) || defined(HOST_X86_64)
2119
    int patch_bytes;
2120
    int retpos;
2121
    int exit_addrs[MAX_EXITS];
2122
#endif
1445
2123
1446
    /* Compute exact size excluding prologue and epilogue instructions.
2124
    /* Compute exact size excluding prologue and epilogue instructions.
1447
     * Increment start_offset to skip epilogue instructions, then compute
2125
     * Increment start_offset to skip epilogue instructions, then compute
Lines 1452-1484 Link Here
1452
    p_end = p_start + size;
2130
    p_end = p_start + size;
1453
    start_offset = offset;
2131
    start_offset = offset;
1454
#if defined(HOST_I386) || defined(HOST_X86_64)
2132
#if defined(HOST_I386) || defined(HOST_X86_64)
1455
#ifdef CONFIG_FORMAT_COFF
1456
    {
1457
        uint8_t *p;
1458
        p = p_end - 1;
1459
        if (p == p_start)
1460
            error("empty code for %s", name);
1461
        while (*p != 0xc3) {
1462
            p--;
1463
            if (p <= p_start)
1464
                error("ret or jmp expected at the end of %s", name);
1465
        }
1466
        copy_size = p - p_start;
1467
    }
1468
#else
1469
    {
2133
    {
1470
        int len;
2134
        int len;
1471
        len = p_end - p_start;
2135
        len = p_end - p_start;
1472
        if (len == 0)
2136
        retpos = trace_i386_op(name, p_start, &len, &patch_bytes, exit_addrs);
1473
            error("empty code for %s", name);
1474
        if (p_end[-1] == 0xc3) {
1475
            len--;
1476
        } else {
1477
            error("ret or jmp expected at the end of %s", name);
1478
        }
1479
        copy_size = len;
2137
        copy_size = len;
1480
    }
2138
    }
1481
#endif
1482
#elif defined(HOST_PPC)
2139
#elif defined(HOST_PPC)
1483
    {
2140
    {
1484
        uint8_t *p;
2141
        uint8_t *p;
Lines 1710-1715 Link Here
1710
    }
2367
    }
1711
2368
1712
    if (gen_switch == 2) {
2369
    if (gen_switch == 2) {
2370
#if defined(HOST_I386) || defined(HOST_X86_64)
2371
        if (patch_bytes != -1)
2372
            copy_size += patch_bytes;
2373
#ifdef DEBUG_OP
2374
        copy_size += 2;
2375
#endif
2376
#endif
1713
        fprintf(outfile, "DEF(%s, %d, %d)\n", name + 3, nb_args, copy_size);
2377
        fprintf(outfile, "DEF(%s, %d, %d)\n", name + 3, nb_args, copy_size);
1714
    } else if (gen_switch == 1) {
2378
    } else if (gen_switch == 1) {
1715
2379
Lines 1915-1921 Link Here
1915
#error unsupport object format
2579
#error unsupport object format
1916
#endif
2580
#endif
1917
                }
2581
                }
2582
               }
2583
                /* Replace the marker instructions with the actual opcodes.  */
2584
                for (i = 0; exit_addrs[i] != -1; i++) {
2585
                    int op;
2586
                    switch (p_start[exit_addrs[i]])
2587
                      {
2588
                      case 0xf4: op = 0xc3; break; /* hlt -> ret */
2589
                      case 0xfa: op = 0xe9; break; /* cli -> jmp */
2590
                      case 0xfb: op = 0xe9; break; /* sti -> jmp */
2591
                      default: error("Internal error");
2592
                      }
2593
                    fprintf(outfile, 
2594
                            "    *(uint8_t *)(gen_code_ptr + %d) = 0x%x;\n",
2595
                            exit_addrs[i], op);
1918
                }
2596
                }
2597
                /* Fix up the return instruction.  */
2598
                if (patch_bytes != -1) {
2599
                    if (patch_bytes) {
2600
                        fprintf(outfile, "    memcpy(gen_code_ptr + %d,"
2601
                                "gen_code_ptr + %d, %d);\n",
2602
                                copy_size, retpos, patch_bytes);
2603
                    }
2604
                    fprintf(outfile,
2605
                            "    *(uint8_t *)(gen_code_ptr + %d) = 0xe9;\n",
2606
                            retpos);
2607
                    fprintf(outfile,
2608
                            "    *(uint32_t *)(gen_code_ptr + %d) = 0x%x;\n",
2609
                            retpos + 1, copy_size - (retpos + 5));
2610
                    
2611
                    copy_size += patch_bytes;
2612
                }
2613
#ifdef DEBUG_OP
2614
                fprintf(outfile,
2615
                        "    *(uint16_t *)(gen_code_ptr + %d) = 0x9090;\n",
2616
                        copy_size);
2617
                copy_size += 2;
2618
#endif
1919
            }
2619
            }
1920
#elif defined(HOST_X86_64)
2620
#elif defined(HOST_X86_64)
1921
            {
2621
            {
Lines 1949-1954 Link Here
1949
                    }
2649
                    }
1950
                }
2650
                }
1951
                }
2651
                }
2652
                /* Replace the marker instructions with the actual opcodes.  */
2653
                for (i = 0; exit_addrs[i] != -1; i++) {
2654
                    int op;
2655
                    switch (p_start[exit_addrs[i]])
2656
                      {
2657
                      case 0xf4: op = 0xc3; break; /* hlt -> ret */
2658
                      case 0xfa: op = 0xe9; break; /* cli -> jmp */
2659
                      case 0xfb: op = 0xe9; break; /* sti -> jmp */
2660
                      default: error("Internal error");
2661
                      }
2662
                    fprintf(outfile, 
2663
                            "    *(uint8_t *)(gen_code_ptr + %d) = 0x%x;\n",
2664
                            exit_addrs[i], op);
2665
                }
2666
                /* Fix up the return instruction.  */
2667
                if (patch_bytes != -1) {
2668
                    if (patch_bytes) {
2669
                        fprintf(outfile, "    memcpy(gen_code_ptr + %d,"
2670
                                "gen_code_ptr + %d, %d);\n",
2671
                                copy_size, retpos, patch_bytes);
2672
                    }
2673
                    fprintf(outfile,
2674
                            "    *(uint8_t *)(gen_code_ptr + %d) = 0xe9;\n",
2675
                            retpos);
2676
                    fprintf(outfile,
2677
                            "    *(uint32_t *)(gen_code_ptr + %d) = 0x%x;\n",
2678
                            retpos + 1, copy_size - (retpos + 5));
2679
                    
2680
                    copy_size += patch_bytes;
2681
                }
2682
#ifdef DEBUG_OP
2683
                fprintf(outfile,
2684
                        "    *(uint16_t *)(gen_code_ptr + %d) = 0x9090;\n",
2685
                        copy_size);
2686
                copy_size += 2;
2687
#endif
1952
            }
2688
            }
1953
#elif defined(HOST_PPC)
2689
#elif defined(HOST_PPC)
1954
            {
2690
            {
(-)qemu-1/qemu/dyngen-exec.h (-4 / +9 lines)
Lines 194-200 Link Here
194
#endif
194
#endif
195
195
196
/* force GCC to generate only one epilog at the end of the function */
196
/* force GCC to generate only one epilog at the end of the function */
197
#if defined(__i386__) || defined(__x86_64__)
198
/* Also add 4 bytes of padding so that we can replace the ret with a jmp.  */
199
#define FORCE_RET() __asm__ __volatile__ ("nop;nop;nop;nop" : : : "memory");
200
#else
197
#define FORCE_RET() __asm__ __volatile__("" : : : "memory");
201
#define FORCE_RET() __asm__ __volatile__("" : : : "memory");
202
#endif
198
203
199
#ifndef OPPROTO
204
#ifndef OPPROTO
200
#define OPPROTO
205
#define OPPROTO
Lines 251-261 Link Here
251
#endif
256
#endif
252
257
253
#if defined(__i386__)
258
#if defined(__i386__)
254
#define EXIT_TB() asm volatile ("ret")
259
#define EXIT_TB() asm volatile ("hlt")
255
#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
260
#define GOTO_LABEL_PARAM(n) asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:")
256
#elif defined(__x86_64__)
261
#elif defined(__x86_64__)
257
#define EXIT_TB() asm volatile ("ret")
262
#define EXIT_TB() asm volatile ("hlt")
258
#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
263
#define GOTO_LABEL_PARAM(n) asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:")
259
#elif defined(__powerpc__)
264
#elif defined(__powerpc__)
260
#define EXIT_TB() asm volatile ("blr")
265
#define EXIT_TB() asm volatile ("blr")
261
#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
266
#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
(-)qemu-1/qemu/exec-all.h (-2 / +3 lines)
Lines 309-322 Link Here
309
309
310
#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
310
#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
311
311
312
/* we patch the jump instruction directly */
312
/* we patch the jump instruction directly.  Use sti in place of the actual
313
   jmp instruction so that dyngen can patch in the correct result.  */
313
#define GOTO_TB(opname, tbparam, n)\
314
#define GOTO_TB(opname, tbparam, n)\
314
do {\
315
do {\
315
    asm volatile (".section .data\n"\
316
    asm volatile (".section .data\n"\
316
		  ASM_OP_LABEL_NAME(n, opname) ":\n"\
317
		  ASM_OP_LABEL_NAME(n, opname) ":\n"\
317
		  ".long 1f\n"\
318
		  ".long 1f\n"\
318
		  ASM_PREVIOUS_SECTION \
319
		  ASM_PREVIOUS_SECTION \
319
                  "jmp " ASM_NAME(__op_jmp) #n "\n"\
320
                  "sti;.long " ASM_NAME(__op_jmp) #n " - 1f\n"\
320
		  "1:\n");\
321
		  "1:\n");\
321
} while (0)
322
} while (0)
322
323
(-)qemu-1/qemu/Makefile.target (+4 lines)
Lines 82-87 Link Here
82
else
82
else
83
QEMU_SYSTEM=qemu-fast
83
QEMU_SYSTEM=qemu-fast
84
endif
84
endif
85
ifeq ($(TARGET_ARCH), x86_64)
86
# XXX globally save %ebx, %esi, %edi on entry to generated function
87
OP_CFLAGS+= -fcall-used-ebx -fcall-used-esi -fcall-used-edi
88
endif
85
89
86
ifdef CONFIG_USER_ONLY
90
ifdef CONFIG_USER_ONLY
87
PROGS=$(QEMU_USER)
91
PROGS=$(QEMU_USER)
(-)qemu-1/qemu/softmmu_header.h (-7 / +6 lines)
Lines 117-123 Link Here
117
                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
117
                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
118
                  "i" (CPU_MMU_INDEX),
118
                  "i" (CPU_MMU_INDEX),
119
                  "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
119
                  "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
120
                  : "%eax", "%ecx", "%edx", "memory", "cc");
120
                  : "%eax", "%edx", "memory", "cc");
121
    return res;
121
    return res;
122
}
122
}
123
123
Lines 164-176 Link Here
164
                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
164
                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
165
                  "i" (CPU_MMU_INDEX),
165
                  "i" (CPU_MMU_INDEX),
166
                  "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
166
                  "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
167
                  : "%eax", "%ecx", "%edx", "memory", "cc");
167
                  : "%eax", "%edx", "memory", "cc");
168
    return res;
168
    return res;
169
}
169
}
170
#endif
170
#endif
171
171
172
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
172
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE val)
173
{
173
{
174
    RES_TYPE v = val;
174
    asm volatile ("movl %0, %%edx\n"
175
    asm volatile ("movl %0, %%edx\n"
175
                  "movl %0, %%eax\n"
176
                  "movl %0, %%eax\n"
176
                  "shrl %3, %%edx\n"
177
                  "shrl %3, %%edx\n"
Lines 207-217 Link Here
207
                  "2:\n"
208
                  "2:\n"
208
                  :
209
                  :
209
                  : "r" (ptr),
210
                  : "r" (ptr),
210
#if DATA_SIZE == 1
211
/* NOTE: 'q' would be needed as constraint, but we could not use it
211
                  "q" (v),
212
   with T1 ! */
212
#else
213
                  "r" (v),
213
                  "r" (v),
214
#endif
215
                  "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
214
                  "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
216
                  "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
215
                  "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
217
                  "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
216
                  "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
(-)qemu-1/qemu/target-arm/op_iwmmxt.c (-1 / +8 lines)
Lines 170-178 Link Here
170
    M0 += M1;
170
    M0 += M1;
171
}
171
}
172
172
173
#if defined(__i386__) && __GNUC__ >= 4
174
#define RegCopy(d, s) __builtin_memcpy(&(d), &(s), sizeof(d))
175
#endif
176
#ifndef RegCopy
177
#define RegCopy(d, s) d = s
178
#endif
179
173
void OPPROTO op_iwmmxt_movq_wRn_M0(void)
180
void OPPROTO op_iwmmxt_movq_wRn_M0(void)
174
{
181
{
175
    M1 = M0;
182
    RegCopy (M1, M0);
176
}
183
}
177
184
178
void OPPROTO op_iwmmxt_movl_wCx_T0(void)
185
void OPPROTO op_iwmmxt_movl_wCx_T0(void)
(-)qemu-1/qemu/target-arm/op_iwmmxt.d (+1 lines)
Line 0 Link Here
1
target-arm/op_iwmmxt.o: target-arm/op_iwmmxt.c
(-)qemu-1/qemu/target-i386/helper.c (+7 lines)
Lines 3607-3614 Link Here
3607
        nb_xmm_regs = 8 << data64;
3607
        nb_xmm_regs = 8 << data64;
3608
        addr = ptr + 0xa0;
3608
        addr = ptr + 0xa0;
3609
        for(i = 0; i < nb_xmm_regs; i++) {
3609
        for(i = 0; i < nb_xmm_regs; i++) {
3610
#if defined(__i386__) && __GNUC__ >= 4
3611
            env->xmm_regs[i].XMM_L(0) = ldl(addr);
3612
            env->xmm_regs[i].XMM_L(1) = ldl(addr + 4);
3613
            env->xmm_regs[i].XMM_L(2) = ldl(addr + 8);
3614
            env->xmm_regs[i].XMM_L(3) = ldl(addr + 12);
3615
#else
3610
            env->xmm_regs[i].XMM_Q(0) = ldq(addr);
3616
            env->xmm_regs[i].XMM_Q(0) = ldq(addr);
3611
            env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
3617
            env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
3618
#endif
3612
            addr += 16;
3619
            addr += 16;
3613
        }
3620
        }
3614
    }
3621
    }
(-)qemu-1/qemu/target-i386/ops_sse.h (-1 / +7 lines)
Lines 34-39 Link Here
34
#define Q(n) XMM_Q(n)
34
#define Q(n) XMM_Q(n)
35
#define SUFFIX _xmm
35
#define SUFFIX _xmm
36
#endif
36
#endif
37
#if defined(__i386__) && __GNUC__ >= 4
38
#define RegCopy(d, s) __builtin_memcpy(&(d), &(s), sizeof(d))
39
#endif
40
#ifndef RegCopy
41
#define RegCopy(d, s) d = s
42
#endif
37
43
38
void OPPROTO glue(op_psrlw, SUFFIX)(void)
44
void OPPROTO glue(op_psrlw, SUFFIX)(void)
39
{
45
{
Lines 589-595 Link Here
589
    r.W(1) = s->W((order >> 2) & 3);
595
    r.W(1) = s->W((order >> 2) & 3);
590
    r.W(2) = s->W((order >> 4) & 3);
596
    r.W(2) = s->W((order >> 4) & 3);
591
    r.W(3) = s->W((order >> 6) & 3);
597
    r.W(3) = s->W((order >> 6) & 3);
592
    *d = r;
598
    RegCopy(*d, r);
593
}
599
}
594
#else
600
#else
595
void OPPROTO op_shufps(void)
601
void OPPROTO op_shufps(void)

Return to bug 160627