VirtualBox

Changeset 2426 in vbox


Ignore:
Timestamp:
Apr 30, 2007 12:36:15 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
20835
Message:

Removed the old recompiler code. (wonder why subversion didn't pick up these changes right way)

Location:
trunk/src/recompiler
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler/target-i386/helper.c

    r1953 r2426  
    1818 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1919 */
     20#ifdef VBOX
     21# include <VBox/err.h>
     22#endif
    2023#include "exec.h"
    21 #ifdef VBOX
    22 #include <VBox/err.h>
    23 #endif
    2424
    2525//#define DEBUG_PCALL
     
    2828#define raise_exception_err(a, b)\
    2929do {\
    30     fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
     30    if (logfile)\
     31        fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
    3132    (raise_exception_err)(a, b);\
    3233} while (0)
     
    224225            if ((e2 & DESC_C_MASK) && dpl > rpl)
    225226                raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
    226                
    227227        } else if (seg_reg == R_SS) {
    228228            /* SS must be writable data */
     
    380380        for(i = 0; i < 6; i++)
    381381            stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector);
    382 
    383382#if defined(VBOX) && defined(DEBUG)
    384383        printf("TSS 32 bits switch\n");
    385384        printf("Saving CS=%08X\n", env->segs[R_CS].selector);
    386385#endif
    387 
    388386    } else {
    389387        /* 16 bit */
     
    567565}
    568566
     567#ifdef TARGET_X86_64
     568#define SET_ESP(val, sp_mask)\
     569do {\
     570    if ((sp_mask) == 0xffff)\
     571        ESP = (ESP & ~0xffff) | ((val) & 0xffff);\
     572    else if ((sp_mask) == 0xffffffffLL)\
     573        ESP = (uint32_t)(val);\
     574    else\
     575        ESP = (val);\
     576} while (0)
     577#else
     578#define SET_ESP(val, sp_mask) ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask))
     579#endif
     580
    569581/* XXX: add a is_user flag to have proper security support */
    570582#define PUSHW(ssp, sp, sp_mask, val)\
     
    598610    SegmentCache *dt;
    599611    target_ulong ptr, ssp;
    600     int type, dpl, selector, ss_dpl, cpl, sp_mask;
     612    int type, dpl, selector, ss_dpl, cpl;
    601613    int has_error_code, new_stack, shift;
    602614    uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2;
    603     uint32_t old_eip;
     615    uint32_t old_eip, sp_mask;
    604616
    605617#ifdef VBOX
     
    642654        switch_tss(intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);
    643655        if (has_error_code) {
    644             int mask, type;
     656            int type;
     657            uint32_t mask;
    645658            /* push the error code */
    646659            type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
     
    656669            else
    657670                stw_kernel(ssp, error_code);
    658             ESP = (esp & mask) | (ESP & ~mask);
     671            SET_ESP(esp, mask);
    659672        }
    660673        return;
     
    787800                               ssp, get_seg_limit(ss_e1, ss_e2), ss_e2);
    788801    }
    789     ESP = (ESP & ~sp_mask) | (esp & sp_mask);
     802    SET_ESP(esp, sp_mask);
    790803
    791804    selector = (selector & ~3) | dpl;
     
    896909        env->eflags &= ~IF_MASK;
    897910}
    898 #endif
     911#endif /* VBOX */
    899912
    900913#ifdef TARGET_X86_64
     
    10781091        cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
    10791092                           0, 0xffffffff,
    1080                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
     1093                               DESC_G_MASK | DESC_P_MASK |
    10811094                               DESC_S_MASK |
    10821095                               DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
     
    11291142            cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
    11301143                                   0, 0xffffffff,
    1131                                    DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
     1144                                   DESC_G_MASK | DESC_P_MASK |
    11321145                                   DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
    11331146                                   DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
     
    11841197void helper_external_event(void)
    11851198{
     1199#if defined(__DARWIN__) && defined(VBOX_STRICT)
     1200# if 0
     1201    //uintptr_t uFrameAddr = (uintptr_t)__builtin_frame_address(0); - this is broken (uses %ebp)
     1202    //AssertMsg(!( (uFrameAddr - sizeof(uintptr_t)) & 7 ), ("uFrameAddr=%#p\n", uFrameAddr));
     1203# else     
     1204    uintptr_t uESP;
     1205    __asm__ __volatile__("movl %%esp, %0" : "=r" (uESP));
     1206    AssertMsg(!(uESP & 15), ("esp=%#p\n", uESP));
     1207# endif
     1208#endif
    11861209    if (env->interrupt_request & CPU_INTERRUPT_EXTERNAL_HARD)
    11871210    {
     
    12781301                  target_ulong next_eip, int is_hw)
    12791302{
    1280 #ifdef DEBUG_PCALL
    1281     if (loglevel & (CPU_LOG_PCALL | CPU_LOG_INT)) {
     1303    if (loglevel & CPU_LOG_INT) {
    12821304        if ((env->cr[0] & CR0_PE_MASK)) {
    12831305            static int count;
     
    12941316            }
    12951317            fprintf(logfile, "\n");
     1318            cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
    12961319#if 0
    1297             cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
    12981320            {
    12991321                int i;
     
    13101332        }
    13111333    }
    1312 #endif
    13131334    if (env->cr[0] & CR0_PE_MASK) {
    13141335#if TARGET_X86_64
     
    13281349                do_soft_interrupt_vme(intno, error_code, next_eip);
    13291350            else
    1330 #endif
     1351#endif /* VBOX */
    13311352                do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
    13321353        }
     
    13761397    raise_interrupt(exception_index, 0, 0, 0);
    13771398}
     1399
     1400/* SMM support */
     1401
     1402#if defined(CONFIG_USER_ONLY)
     1403
     1404void do_smm_enter(void)
     1405{
     1406}
     1407
     1408void helper_rsm(void)
     1409{
     1410}
     1411
     1412#else
     1413
     1414#ifdef TARGET_X86_64
     1415#define SMM_REVISION_ID 0x00020064
     1416#else
     1417#define SMM_REVISION_ID 0x00020000
     1418#endif
     1419
     1420void do_smm_enter(void)
     1421{
     1422#ifdef VBOX
     1423    cpu_abort(env, "do_ssm_enter");
     1424#else /* !VBOX */
     1425    target_ulong sm_state;
     1426    SegmentCache *dt;
     1427    int i, offset;
     1428
     1429    if (loglevel & CPU_LOG_INT) {
     1430        fprintf(logfile, "SMM: enter\n");
     1431        cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
     1432    }
     1433
     1434    env->hflags |= HF_SMM_MASK;
     1435    cpu_smm_update(env);
     1436
     1437    sm_state = env->smbase + 0x8000;
     1438   
     1439#ifdef TARGET_X86_64
     1440    for(i = 0; i < 6; i++) {
     1441        dt = &env->segs[i];
     1442        offset = 0x7e00 + i * 16;
     1443        stw_phys(sm_state + offset, dt->selector);
     1444        stw_phys(sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff);
     1445        stl_phys(sm_state + offset + 4, dt->limit);
     1446        stq_phys(sm_state + offset + 8, dt->base);
     1447    }
     1448
     1449    stq_phys(sm_state + 0x7e68, env->gdt.base);
     1450    stl_phys(sm_state + 0x7e64, env->gdt.limit);
     1451
     1452    stw_phys(sm_state + 0x7e70, env->ldt.selector);
     1453    stq_phys(sm_state + 0x7e78, env->ldt.base);
     1454    stl_phys(sm_state + 0x7e74, env->ldt.limit);
     1455    stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);
     1456   
     1457    stq_phys(sm_state + 0x7e88, env->idt.base);
     1458    stl_phys(sm_state + 0x7e84, env->idt.limit);
     1459
     1460    stw_phys(sm_state + 0x7e90, env->tr.selector);
     1461    stq_phys(sm_state + 0x7e98, env->tr.base);
     1462    stl_phys(sm_state + 0x7e94, env->tr.limit);
     1463    stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);
     1464   
     1465    stq_phys(sm_state + 0x7ed0, env->efer);
     1466
     1467    stq_phys(sm_state + 0x7ff8, EAX);
     1468    stq_phys(sm_state + 0x7ff0, ECX);
     1469    stq_phys(sm_state + 0x7fe8, EDX);
     1470    stq_phys(sm_state + 0x7fe0, EBX);
     1471    stq_phys(sm_state + 0x7fd8, ESP);
     1472    stq_phys(sm_state + 0x7fd0, EBP);
     1473    stq_phys(sm_state + 0x7fc8, ESI);
     1474    stq_phys(sm_state + 0x7fc0, EDI);
     1475    for(i = 8; i < 16; i++)
     1476        stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]);
     1477    stq_phys(sm_state + 0x7f78, env->eip);
     1478    stl_phys(sm_state + 0x7f70, compute_eflags());
     1479    stl_phys(sm_state + 0x7f68, env->dr[6]);
     1480    stl_phys(sm_state + 0x7f60, env->dr[7]);
     1481
     1482    stl_phys(sm_state + 0x7f48, env->cr[4]);
     1483    stl_phys(sm_state + 0x7f50, env->cr[3]);
     1484    stl_phys(sm_state + 0x7f58, env->cr[0]);
     1485
     1486    stl_phys(sm_state + 0x7efc, SMM_REVISION_ID);
     1487    stl_phys(sm_state + 0x7f00, env->smbase);
     1488#else
     1489    stl_phys(sm_state + 0x7ffc, env->cr[0]);
     1490    stl_phys(sm_state + 0x7ff8, env->cr[3]);
     1491    stl_phys(sm_state + 0x7ff4, compute_eflags());
     1492    stl_phys(sm_state + 0x7ff0, env->eip);
     1493    stl_phys(sm_state + 0x7fec, EDI);
     1494    stl_phys(sm_state + 0x7fe8, ESI);
     1495    stl_phys(sm_state + 0x7fe4, EBP);
     1496    stl_phys(sm_state + 0x7fe0, ESP);
     1497    stl_phys(sm_state + 0x7fdc, EBX);
     1498    stl_phys(sm_state + 0x7fd8, EDX);
     1499    stl_phys(sm_state + 0x7fd4, ECX);
     1500    stl_phys(sm_state + 0x7fd0, EAX);
     1501    stl_phys(sm_state + 0x7fcc, env->dr[6]);
     1502    stl_phys(sm_state + 0x7fc8, env->dr[7]);
     1503   
     1504    stl_phys(sm_state + 0x7fc4, env->tr.selector);
     1505    stl_phys(sm_state + 0x7f64, env->tr.base);
     1506    stl_phys(sm_state + 0x7f60, env->tr.limit);
     1507    stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);
     1508   
     1509    stl_phys(sm_state + 0x7fc0, env->ldt.selector);
     1510    stl_phys(sm_state + 0x7f80, env->ldt.base);
     1511    stl_phys(sm_state + 0x7f7c, env->ldt.limit);
     1512    stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);
     1513   
     1514    stl_phys(sm_state + 0x7f74, env->gdt.base);
     1515    stl_phys(sm_state + 0x7f70, env->gdt.limit);
     1516
     1517    stl_phys(sm_state + 0x7f58, env->idt.base);
     1518    stl_phys(sm_state + 0x7f54, env->idt.limit);
     1519
     1520    for(i = 0; i < 6; i++) {
     1521        dt = &env->segs[i];
     1522        if (i < 3)
     1523            offset = 0x7f84 + i * 12;
     1524        else
     1525            offset = 0x7f2c + (i - 3) * 12;
     1526        stl_phys(sm_state + 0x7fa8 + i * 4, dt->selector);
     1527        stl_phys(sm_state + offset + 8, dt->base);
     1528        stl_phys(sm_state + offset + 4, dt->limit);
     1529        stl_phys(sm_state + offset, (dt->flags >> 8) & 0xf0ff);
     1530    }
     1531    stl_phys(sm_state + 0x7f14, env->cr[4]);
     1532
     1533    stl_phys(sm_state + 0x7efc, SMM_REVISION_ID);
     1534    stl_phys(sm_state + 0x7ef8, env->smbase);
     1535#endif
     1536    /* init SMM cpu state */
     1537
     1538#ifdef TARGET_X86_64
     1539    env->efer = 0;
     1540    env->hflags &= ~HF_LMA_MASK;
     1541#endif
     1542    load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
     1543    env->eip = 0x00008000;
     1544    cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
     1545                           0xffffffff, 0);
     1546    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0);
     1547    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0);
     1548    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0);
     1549    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0);
     1550    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0);
     1551   
     1552    cpu_x86_update_cr0(env,
     1553                       env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK));
     1554    cpu_x86_update_cr4(env, 0);
     1555    env->dr[7] = 0x00000400;
     1556    CC_OP = CC_OP_EFLAGS;
     1557#endif /* VBOX */
     1558}
     1559
     1560void helper_rsm(void)
     1561{
     1562#ifdef VBOX
     1563   cpu_abort(env, "helper_rsm");
     1564#else /* !VBOX */
     1565    target_ulong sm_state;
     1566    int i, offset;
     1567    uint32_t val;
     1568
     1569    sm_state = env->smbase + 0x8000;
     1570#ifdef TARGET_X86_64
     1571    env->efer = ldq_phys(sm_state + 0x7ed0);
     1572    if (env->efer & MSR_EFER_LMA)
     1573        env->hflags |= HF_LMA_MASK;
     1574    else
     1575        env->hflags &= ~HF_LMA_MASK;
     1576
     1577    for(i = 0; i < 6; i++) {
     1578        offset = 0x7e00 + i * 16;
     1579        cpu_x86_load_seg_cache(env, i,
     1580                               lduw_phys(sm_state + offset),
     1581                               ldq_phys(sm_state + offset + 8),
     1582                               ldl_phys(sm_state + offset + 4),
     1583                               (lduw_phys(sm_state + offset + 2) & 0xf0ff) << 8);
     1584    }
     1585
     1586    env->gdt.base = ldq_phys(sm_state + 0x7e68);
     1587    env->gdt.limit = ldl_phys(sm_state + 0x7e64);
     1588
     1589    env->ldt.selector = lduw_phys(sm_state + 0x7e70);
     1590    env->ldt.base = ldq_phys(sm_state + 0x7e78);
     1591    env->ldt.limit = ldl_phys(sm_state + 0x7e74);
     1592    env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8;
     1593   
     1594    env->idt.base = ldq_phys(sm_state + 0x7e88);
     1595    env->idt.limit = ldl_phys(sm_state + 0x7e84);
     1596
     1597    env->tr.selector = lduw_phys(sm_state + 0x7e90);
     1598    env->tr.base = ldq_phys(sm_state + 0x7e98);
     1599    env->tr.limit = ldl_phys(sm_state + 0x7e94);
     1600    env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8;
     1601   
     1602    EAX = ldq_phys(sm_state + 0x7ff8);
     1603    ECX = ldq_phys(sm_state + 0x7ff0);
     1604    EDX = ldq_phys(sm_state + 0x7fe8);
     1605    EBX = ldq_phys(sm_state + 0x7fe0);
     1606    ESP = ldq_phys(sm_state + 0x7fd8);
     1607    EBP = ldq_phys(sm_state + 0x7fd0);
     1608    ESI = ldq_phys(sm_state + 0x7fc8);
     1609    EDI = ldq_phys(sm_state + 0x7fc0);
     1610    for(i = 8; i < 16; i++)
     1611        env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8);
     1612    env->eip = ldq_phys(sm_state + 0x7f78);
     1613    load_eflags(ldl_phys(sm_state + 0x7f70),
     1614                ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
     1615    env->dr[6] = ldl_phys(sm_state + 0x7f68);
     1616    env->dr[7] = ldl_phys(sm_state + 0x7f60);
     1617
     1618    cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f48));
     1619    cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7f50));
     1620    cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7f58));
     1621
     1622    val = ldl_phys(sm_state + 0x7efc); /* revision ID */
     1623    if (val & 0x20000) {
     1624        env->smbase = ldl_phys(sm_state + 0x7f00) & ~0x7fff;
     1625    }
     1626#else
     1627    cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7ffc));
     1628    cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7ff8));
     1629    load_eflags(ldl_phys(sm_state + 0x7ff4),
     1630                ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
     1631    env->eip = ldl_phys(sm_state + 0x7ff0);
     1632    EDI = ldl_phys(sm_state + 0x7fec);
     1633    ESI = ldl_phys(sm_state + 0x7fe8);
     1634    EBP = ldl_phys(sm_state + 0x7fe4);
     1635    ESP = ldl_phys(sm_state + 0x7fe0);
     1636    EBX = ldl_phys(sm_state + 0x7fdc);
     1637    EDX = ldl_phys(sm_state + 0x7fd8);
     1638    ECX = ldl_phys(sm_state + 0x7fd4);
     1639    EAX = ldl_phys(sm_state + 0x7fd0);
     1640    env->dr[6] = ldl_phys(sm_state + 0x7fcc);
     1641    env->dr[7] = ldl_phys(sm_state + 0x7fc8);
     1642   
     1643    env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff;
     1644    env->tr.base = ldl_phys(sm_state + 0x7f64);
     1645    env->tr.limit = ldl_phys(sm_state + 0x7f60);
     1646    env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8;
     1647   
     1648    env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff;
     1649    env->ldt.base = ldl_phys(sm_state + 0x7f80);
     1650    env->ldt.limit = ldl_phys(sm_state + 0x7f7c);
     1651    env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8;
     1652   
     1653    env->gdt.base = ldl_phys(sm_state + 0x7f74);
     1654    env->gdt.limit = ldl_phys(sm_state + 0x7f70);
     1655
     1656    env->idt.base = ldl_phys(sm_state + 0x7f58);
     1657    env->idt.limit = ldl_phys(sm_state + 0x7f54);
     1658
     1659    for(i = 0; i < 6; i++) {
     1660        if (i < 3)
     1661            offset = 0x7f84 + i * 12;
     1662        else
     1663            offset = 0x7f2c + (i - 3) * 12;
     1664        cpu_x86_load_seg_cache(env, i,
     1665                               ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff,
     1666                               ldl_phys(sm_state + offset + 8),
     1667                               ldl_phys(sm_state + offset + 4),
     1668                               (ldl_phys(sm_state + offset) & 0xf0ff) << 8);
     1669    }
     1670    cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f14));
     1671
     1672    val = ldl_phys(sm_state + 0x7efc); /* revision ID */
     1673    if (val & 0x20000) {
     1674        env->smbase = ldl_phys(sm_state + 0x7ef8) & ~0x7fff;
     1675    }
     1676#endif
     1677    CC_OP = CC_OP_EFLAGS;
     1678    env->hflags &= ~HF_SMM_MASK;
     1679    cpu_smm_update(env);
     1680
     1681    if (loglevel & CPU_LOG_INT) {
     1682        fprintf(logfile, "SMM: after RSM\n");
     1683        cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
     1684    }
     1685#endif /* !VBOX */
     1686}
     1687
     1688#endif /* !CONFIG_USER_ONLY */
     1689
    13781690
    13791691#ifdef BUGGY_GCC_DIV64
     
    14581770{
    14591771#ifndef VBOX
    1460     switch((uint32_t)EAX) {
     1772    uint32_t index;
     1773    index = (uint32_t)EAX;
     1774   
     1775    /* test if maximum index reached */
     1776    if (index & 0x80000000) {
     1777        if (index > env->cpuid_xlevel)
     1778            index = env->cpuid_level;
     1779    } else {
     1780        if (index > env->cpuid_level)
     1781            index = env->cpuid_level;
     1782    }
     1783       
     1784    switch(index) {
    14611785    case 0:
    1462         EAX = 2; /* max EAX index supported */
     1786        EAX = env->cpuid_level;
    14631787        EBX = env->cpuid_vendor1;
    14641788        EDX = env->cpuid_vendor2;
     
    14671791    case 1:
    14681792        EAX = env->cpuid_version;
    1469         EBX = 0;
     1793        EBX = 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
    14701794        ECX = env->cpuid_ext_features;
    14711795        EDX = env->cpuid_features;
    14721796        break;
    1473 
    1474     default:
     1797    case 2:
    14751798        /* cache info: needed for Pentium Pro compatibility */
    14761799        EAX = 0x410601;
     
    14791802        EDX = 0;
    14801803        break;
    1481 
    1482 #ifdef TARGET_X86_64
    14831804    case 0x80000000:
    1484         EAX = 0x80000008;
     1805        EAX = env->cpuid_xlevel;
    14851806        EBX = env->cpuid_vendor1;
    14861807        EDX = env->cpuid_vendor2;
     
    14911812        EBX = 0;
    14921813        ECX = 0;
    1493         /* long mode + syscall/sysret features */
    1494         EDX = (env->cpuid_features & 0x0183F3FF) | (1 << 29) | (1 << 11);
     1814        EDX = env->cpuid_ext2_features;
     1815        break;
     1816    case 0x80000002:
     1817    case 0x80000003:
     1818    case 0x80000004:
     1819        EAX = env->cpuid_model[(index - 0x80000002) * 4 + 0];
     1820        EBX = env->cpuid_model[(index - 0x80000002) * 4 + 1];
     1821        ECX = env->cpuid_model[(index - 0x80000002) * 4 + 2];
     1822        EDX = env->cpuid_model[(index - 0x80000002) * 4 + 3];
     1823        break;
     1824    case 0x80000005:
     1825        /* cache info (L1 cache) */
     1826        EAX = 0x01ff01ff;
     1827        EBX = 0x01ff01ff;
     1828        ECX = 0x40020140;
     1829        EDX = 0x40020140;
     1830        break;
     1831    case 0x80000006:
     1832        /* cache info (L2 cache) */
     1833        EAX = 0;
     1834        EBX = 0x42004200;
     1835        ECX = 0x02008140;
     1836        EDX = 0;
    14951837        break;
    14961838    case 0x80000008:
     
    15011843        EDX = 0;
    15021844        break;
    1503 #endif
     1845    default:
     1846        /* reserved values: zero */
     1847        EAX = 0;
     1848        EBX = 0;
     1849        ECX = 0;
     1850        EDX = 0;
     1851        break;
    15041852    }
    15051853#else /* VBOX */
     
    16341982    int index, type, entry_limit;
    16351983    target_ulong ptr;
     1984   
    16361985#ifdef VBOX
    16371986    Log(("helper_ltr_T0: old tr=%RTsel {.base=%VGv, .limit=%VGv, .flags=%RX32} new=%RTsel\n",
     
    17502099            if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
    17512100                /* if not conforming code, test rights */
    1752                 if (dpl < cpl || dpl < rpl)
     2101                if (dpl < cpl || dpl < rpl) 
    17532102                    raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
    17542103            }
     
    18902239    }
    18912240
    1892     ESP = (ESP & ~esp_mask) | (esp & esp_mask);
     2241    SET_ESP(esp, esp_mask);
    18932242    env->eip = new_eip;
    18942243    env->segs[R_CS].selector = new_cs;
     
    19762325                raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
    19772326            /* from this point, not restartable */
    1978             ESP = (ESP & ~sp_mask) | (sp & sp_mask);
     2327            SET_ESP(sp, sp_mask);
    19792328            cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
    19802329                                   get_seg_base(e1, e2), limit, e2);
     
    21052454                       e2);
    21062455        cpu_x86_set_cpl(env, dpl);
    2107         ESP = (ESP & ~sp_mask) | (sp & sp_mask);
     2456        SET_ESP(sp, sp_mask);
    21082457        EIP = offset;
    21092458    }
     
    21222471    target_ulong ssp;
    21232472    int eflags_mask;
    2124 
    21252473#ifdef VBOX
    21262474    bool fVME = false;
    21272475
    21282476    remR3TrapClear(env->pVM);
    2129 #endif
     2477#endif /* VBOX */
    21302478
    21312479    sp_mask = 0xffff; /* XXXX: use SS segment size ? */
     
    21542502        if (    ((new_eflags & IF_MASK) && (env->eflags & VIP_MASK))
    21552503            ||  (new_eflags & TF_MASK))
    2156         {
    21572504            raise_exception(EXCP0D_GPF);
    2158         }
    2159     }
    2160 #endif
     2505    }
     2506#endif /* VBOX */
    21612507
    21622508    ESP = (ESP & ~sp_mask) | (sp & sp_mask);
     
    21742520    if (shift == 0)
    21752521        eflags_mask &= 0xffff;
    2176 
    21772522    load_eflags(new_eflags, eflags_mask);
    21782523
     
    21852530            env->eflags &= ~VIF_MASK;
    21862531    }
    2187 #endif
     2532#endif /* VBOX */
    21882533}
    21892534
     
    21922537    int dpl;
    21932538    uint32_t e2;
    2194    
     2539
     2540    /* XXX: on x86_64, we do not want to nullify FS and GS because
     2541       they may still contain a valid base. I would be interested to
     2542       know how a real x86_64 CPU behaves */
     2543    if ((seg_reg == R_FS || seg_reg == R_GS) &&
     2544        (env->segs[seg_reg].selector & 0xfffc) == 0)
     2545        return;
     2546
    21952547    e2 = env->segs[seg_reg].flags;
    21962548    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
     
    22172569    else
    22182570#endif
    2219     sp_mask = get_sp_mask(env->segs[R_SS].flags);
     2571        sp_mask = get_sp_mask(env->segs[R_SS].flags);
    22202572    sp = ESP;
    22212573    ssp = env->segs[R_SS].base;
     
    23632715#ifdef TARGET_X86_64
    23642716            /* NULL ss is allowed in long mode if cpl != 3*/
     2717            /* XXX: test CS64 ? */
    23652718            if ((env->hflags & HF_LMA_MASK) && rpl != 3) {
    23662719                cpu_x86_load_seg_cache(env, R_SS, new_ss,
     
    23692722                                       DESC_S_MASK | (rpl << DESC_DPL_SHIFT) |
    23702723                                       DESC_W_MASK | DESC_A_MASK);
     2724                ss_e2 = DESC_B_MASK; /* XXX: should not be needed ? */
    23712725            } else
    23722726#endif
     
    24152769        sp += addend;
    24162770    }
    2417     ESP = (ESP & ~sp_mask) | (sp & sp_mask);
     2771    SET_ESP(sp, sp_mask);
    24182772    env->eip = new_eip;
    24192773    if (is_iret) {
     
    24262780            eflags_mask |= IOPL_MASK;
    24272781#endif
    2428 
    24292782        iopl = (env->eflags >> IOPL_SHIFT) & 3;
    24302783        if (cpl <= iopl)
     
    24952848        helper_ret_protected(shift, 1, 0);
    24962849    }
     2850#ifdef USE_KQEMU
     2851    if (kqemu_is_ok(env)) {
     2852        CC_OP = CC_OP_EFLAGS;
     2853        env->exception_index = -1;
     2854        cpu_loop_exit();
     2855    }
     2856#endif
    24972857}
    24982858
     
    25002860{
    25012861    helper_ret_protected(shift, 0, addend);
     2862#ifdef USE_KQEMU
     2863    if (kqemu_is_ok(env)) {
     2864        env->exception_index = -1;
     2865        cpu_loop_exit();
     2866    }
     2867#endif
    25022868}
    25032869
     
    25442910    ESP = ECX;
    25452911    EIP = EDX;
     2912#ifdef USE_KQEMU
     2913    if (kqemu_is_ok(env)) {
     2914        env->exception_index = -1;
     2915        cpu_loop_exit();
     2916    }
     2917#endif
    25462918}
    25472919
     
    25752947}
    25762948
    2577 void helper_invlpg(unsigned int addr)
     2949void helper_invlpg(target_ulong addr)
    25782950{
    25792951    cpu_x86_flush_tlb(env, addr);
     
    25862958    if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
    25872959        raise_exception(EXCP0D_GPF);
    2588     }   
     2960    }
    25892961    val = cpu_get_tsc(env);
    25902962    EAX = (uint32_t)(val);
     
    26202992        cpu_set_apic_base(env, val);
    26212993        break;
    2622 #ifdef TARGET_X86_64
    26232994    case MSR_EFER:
    2624 #define MSR_EFER_UPDATE_MASK (MSR_EFER_SCE | MSR_EFER_LME | \
    2625                               MSR_EFER_NXE | MSR_EFER_FFXSR)
    2626         env->efer = (env->efer & ~MSR_EFER_UPDATE_MASK) |
    2627             (val & MSR_EFER_UPDATE_MASK);
     2995        {
     2996            uint64_t update_mask;
     2997            update_mask = 0;
     2998            if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL)
     2999                update_mask |= MSR_EFER_SCE;
     3000            if (env->cpuid_ext2_features & CPUID_EXT2_LM)
     3001                update_mask |= MSR_EFER_LME;
     3002            if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR)
     3003                update_mask |= MSR_EFER_FFXSR;
     3004            if (env->cpuid_ext2_features & CPUID_EXT2_NX)
     3005                update_mask |= MSR_EFER_NXE;
     3006            env->efer = (env->efer & ~update_mask) |
     3007            (val & update_mask);
     3008        }
    26283009        break;
    26293010    case MSR_STAR:
    26303011        env->star = val;
    26313012        break;
     3013    case MSR_PAT:
     3014        env->pat = val;
     3015        break;
     3016#ifdef TARGET_X86_64
    26323017    case MSR_LSTAR:
    26333018        env->lstar = val;
     
    26713056        val = cpu_get_apic_base(env);
    26723057        break;
    2673 #ifdef TARGET_X86_64
    26743058    case MSR_EFER:
    26753059        val = env->efer;
     
    26783062        val = env->star;
    26793063        break;
     3064    case MSR_PAT:
     3065        val = env->pat;
     3066        break;
     3067#ifdef TARGET_X86_64
    26803068    case MSR_LSTAR:
    26813069        val = env->lstar;
     
    29273315void helper_fbst_ST0_A0(void)
    29283316{
    2929     CPU86_LDouble tmp;
    29303317    int v;
    29313318    target_ulong mem_ref, mem_end;
    29323319    int64_t val;
    29333320
    2934     tmp = rint(ST0);
    2935     val = (int64_t)tmp;
     3321    val = floatx_to_int64(ST0, &env->fp_status);
    29363322    mem_ref = A0;
    29373323    mem_end = mem_ref + 9;
     
    31263512void helper_frndint(void)
    31273513{
    3128     CPU86_LDouble a;
    3129 
    3130     a = ST0;
    3131 #ifdef __arm__
    3132     switch(env->fpuc & RC_MASK) {
    3133     default:
    3134     case RC_NEAR:
    3135         asm("rndd %0, %1" : "=f" (a) : "f"(a));
    3136         break;
    3137     case RC_DOWN:
    3138         asm("rnddm %0, %1" : "=f" (a) : "f"(a));
    3139         break;
    3140     case RC_UP:
    3141         asm("rnddp %0, %1" : "=f" (a) : "f"(a));
    3142         break;
    3143     case RC_CHOP:
    3144         asm("rnddz %0, %1" : "=f" (a) : "f"(a));
    3145         break;
    3146     }
    3147 #else
    3148     a = rint(a);
    3149 #endif
    3150     ST0 = a;
     3514    ST0 = floatx_round_to_int(ST0, &env->fp_status);
    31513515}
    31523516
    31533517void helper_fscale(void)
    31543518{
    3155     CPU86_LDouble fpsrcop, fptemp;
    3156 
    3157     fpsrcop = 2.0;
    3158     fptemp = pow(fpsrcop,ST1);
    3159     ST0 *= fptemp;
     3519    ST0 = ldexp (ST0, (int)(ST1));
    31603520}
    31613521
     
    33953755
    33963756    if (env->cr[4] & CR4_OSFXSR_MASK) {
    3397         /* XXX: finish it, endianness */
     3757        /* XXX: finish it */
    33983758        env->mxcsr = ldl(ptr + 0x18);
    33993759        //ldl(ptr + 0x1c);
     
    35233883    *phigh += v;
    35243884#ifdef DEBUG_MULDIV
    3525     printf("mul: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
     3885    printf("mul: 0x%016" PRIx64 " * 0x%016" PRIx64 " = 0x%016" PRIx64 "%016" PRIx64 "\n",
    35263886           a, b, *phigh, *plow);
    35273887#endif
     
    35723932        }
    35733933#if defined(DEBUG_MULDIV)
    3574         printf("div: 0x%016llx%016llx / 0x%016llx: q=0x%016llx r=0x%016llx\n",
     3934        printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64 ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n",
    35753935               *phigh, *plow, b, a0, a1);
    35763936#endif
     
    36664026}
    36674027
    3668 #endif
    3669 
    3670 /* XXX: do it */
    3671 int fpu_isnan(double a)
    3672 {
    3673     return 0;
    3674 }
     4028void helper_bswapq_T0(void)
     4029{
     4030    T0 = bswap64(T0);
     4031}
     4032#endif
    36754033
    36764034void helper_hlt(void)
    36774035{
    36784036    env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
     4037    env->hflags |= HF_HALTED_MASK;
    36794038    env->exception_index = EXCP_HLT;
    36804039    cpu_loop_exit();
     
    36834042void helper_monitor(void)
    36844043{
    3685     if (ECX != 0)
     4044    if ((uint32_t)ECX != 0)
    36864045        raise_exception(EXCP0D_GPF);
    36874046    /* XXX: store address ? */
     
    36904049void helper_mwait(void)
    36914050{
    3692     if (ECX != 0)
     4051    if ((uint32_t)ECX != 0)
    36934052        raise_exception(EXCP0D_GPF);
    36944053#ifdef VBOX
     
    37154074}
    37164075
    3717 /* XXX: find a better solution */
    3718 double helper_sqrt(double a)
    3719 {
    3720     return sqrt(a);
     4076void update_fp_status(void)
     4077{
     4078    int rnd_type;
     4079
     4080    /* set rounding mode */
     4081    switch(env->fpuc & RC_MASK) {
     4082    default:
     4083    case RC_NEAR:
     4084        rnd_type = float_round_nearest_even;
     4085        break;
     4086    case RC_DOWN:
     4087        rnd_type = float_round_down;
     4088        break;
     4089    case RC_UP:
     4090        rnd_type = float_round_up;
     4091        break;
     4092    case RC_CHOP:
     4093        rnd_type = float_round_to_zero;
     4094        break;
     4095    }
     4096    set_float_rounding_mode(rnd_type, &env->fp_status);
     4097#ifdef FLOATX80
     4098    switch((env->fpuc >> 8) & 3) {
     4099    case 0:
     4100        rnd_type = 32;
     4101        break;
     4102    case 2:
     4103        rnd_type = 64;
     4104        break;
     4105    case 3:
     4106    default:
     4107        rnd_type = 80;
     4108        break;
     4109    }
     4110    set_floatx80_rounding_precision(rnd_type, &env->fp_status);
     4111#endif
    37214112}
    37224113
     
    37694160        }
    37704161        if (retaddr)
    3771             raise_exception_err(EXCP0E_PAGE, env->error_code);
    3772         else {
    3773             raise_exception_err_norestore(EXCP0E_PAGE, env->error_code);
    3774         }
     4162            raise_exception_err(env->exception_index, env->error_code);
     4163        else
     4164            raise_exception_err_norestore(env->exception_index, env->error_code);
    37754165    }
    37764166    env = saved_env;
    37774167}
    37784168
    3779 #if defined(VBOX)
     4169#ifdef VBOX
    37804170
    37814171/**
     
    40294419    int csize;
    40304420    void (*gen_func)(void);
    4031     uint8_t *pvCode;
     4421    uint8_t *tc_ptr;
    40324422    uint32_t old_eip;
    40334423
     
    40384428    RAWEx_ProfileStart(env, STATS_EMULATE_SINGLE_INSTR);
    40394429
    4040     pvCode = env->pvCodeBuffer;
    4041 
    4042     // Setup temporary translation block
    4043     tb_temp.hash_next = 0;
    4044     tb_temp.jmp_first = 0;
    4045     tb_temp.jmp_next[0] = 0;
    4046     tb_temp.jmp_next[1] = 0;
     4430    tc_ptr = env->pvCodeBuffer;
     4431
     4432    /*
     4433     * Setup temporary translation block.
     4434     */
     4435    /* tb_alloc: */
     4436    tb_temp.pc = env->segs[R_CS].base + env->eip;
     4437    tb_temp.cflags = 0;
     4438
     4439    /* tb_find_slow: */
     4440    tb_temp.tc_ptr = tc_ptr;
     4441    tb_temp.cs_base = env->segs[R_CS].base;
     4442    tb_temp.flags = env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
     4443
     4444    /* Initialize the rest with sensible values. */
     4445    tb_temp.size = 0;
     4446    tb_temp.phys_hash_next = NULL;
     4447    tb_temp.page_next[0] = NULL;
     4448    tb_temp.page_next[1] = NULL;
    40474449    tb_temp.page_addr[0] = 0;
    40484450    tb_temp.page_addr[1] = 0;
    4049     tb_temp.page_next[0] = 0;
    4050     tb_temp.page_next[1] = 0;
    4051     tb_temp.hash_next = 0;
    4052 
    40534451    tb_temp.tb_next_offset[0] = 0xffff;
    40544452    tb_temp.tb_next_offset[1] = 0xffff;
    4055 
    4056     tb_temp.cs_base = (unsigned long)env->segs[R_CS].base;
    4057     tb_temp.pc      = tb_temp.cs_base + env->eip;
    4058     tb_temp.cflags  = 0;
    4059     tb_temp.flags   = env->hflags;
    4060     tb_temp.flags  |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
    4061     tb_temp.tc_ptr  = pvCode;
     4453    tb_temp.tb_next[0] = 0xffff;
     4454    tb_temp.tb_next[1] = 0xffff;
     4455    tb_temp.jmp_next[0] = NULL;
     4456    tb_temp.jmp_next[1] = NULL;
     4457    tb_temp.jmp_first = NULL;
    40624458
    40634459    current = env->current_tb;
    40644460    env->current_tb = NULL;
    40654461
    4066     // Translate only one instruction
    4067     ASMAtomicOrS32(&env->state, CPU_EMULATE_SINGLE_INSTR);
     4462    /*
     4463     * Translate only one instruction.
     4464     */
     4465    ASMAtomicOrU32(&env->state, CPU_EMULATE_SINGLE_INSTR);
    40684466    if (cpu_gen_code(env, &tb_temp, env->cbCodeBuffer, &csize) < 0)
    40694467    {
    40704468        AssertFailed();
    40714469        RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR);
    4072         ASMAtomicAndS32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
     4470        ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
    40734471        env = savedenv;
    40744472        return -1;
     
    40794477        RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR);
    40804478        AssertFailed();
    4081         ASMAtomicAndS32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
     4479        ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
    40824480        env = savedenv;
    40834481        return -1;
    40844482    }
    4085     if (tb_temp.tc_ptr != pvCode)
     4483    if (tb_temp.tc_ptr != tc_ptr)
    40864484    {
    40874485        RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR);
    40884486        AssertFailed();
    4089         ASMAtomicAndS32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
     4487        ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
    40904488        env = savedenv;
    40914489        return -1;
    40924490    }
    40934491#endif
    4094     ASMAtomicAndS32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
    4095 
    4096     tb_link(&tb_temp);
    4097 
     4492    ASMAtomicAndU32(&env->state, ~CPU_EMULATE_SINGLE_INSTR);
     4493
     4494    /* tb_link_phys: */
     4495    tb_temp.jmp_first = (TranslationBlock *)((intptr_t)&tb_temp | 2);
     4496    Assert(tb_temp.jmp_next[0] == NULL); Assert(tb_temp.jmp_next[1] == NULL);
     4497    if (tb_temp.tb_next_offset[0] != 0xffff)
     4498        tb_set_jmp_target(&tb_temp, 0, (uintptr_t)(tb_temp.tc_ptr + tb_temp.tb_next_offset[0]));
     4499    if (tb_temp.tb_next_offset[1] != 0xffff)
     4500        tb_set_jmp_target(&tb_temp, 1, (uintptr_t)(tb_temp.tc_ptr + tb_temp.tb_next_offset[1]));
     4501
     4502    /*
     4503     * Execute it using emulation
     4504     */
    40984505    old_eip = env->eip;
    4099     // Execute it using emulation
    41004506    gen_func = (void *)tb_temp.tc_ptr;
    41014507    env->current_tb = &tb_temp;
     
    41194525    env->current_tb = current;
    41204526
     4527    Assert(tb_temp.phys_hash_next == NULL);
     4528    Assert(tb_temp.page_next[0] == NULL);
     4529    Assert(tb_temp.page_next[1] == NULL);
     4530    Assert(tb_temp.page_addr[0] == 0);
     4531    Assert(tb_temp.page_addr[1] == 0);
     4532/*
     4533    Assert(tb_temp.tb_next_offset[0] == 0xffff);
     4534    Assert(tb_temp.tb_next_offset[1] == 0xffff);
     4535    Assert(tb_temp.tb_next[0] == 0xffff);
     4536    Assert(tb_temp.tb_next[1] == 0xffff);
     4537    Assert(tb_temp.jmp_next[0] == NULL);
     4538    Assert(tb_temp.jmp_next[1] == NULL);
     4539    Assert(tb_temp.jmp_first == NULL); */
     4540   
    41214541    RAWEx_ProfileStop(env, STATS_EMULATE_SINGLE_INSTR);
    41224542
     4543    /*                                                             
     4544     * Execute the next instruction when we encounter instruction fusing.
     4545     */
    41234546    if (env->hflags & HF_INHIBIT_IRQ_MASK)
    41244547    {
  • trunk/src/recompiler/tests/Makefile

    r1 r2426  
    1 #-include ../config-host.mak
    2 CC=gcc
     1-include ../config-host.mak
     2
    33CFLAGS=-Wall -O2 -g
     4#CFLAGS+=-msse2
    45LDFLAGS=
    56
    67ifeq ($(ARCH),i386)
    78TESTS=linux-test testthread sha1-i386 test-i386 runcom
     9endif
     10ifeq ($(ARCH),x86_64)
     11TESTS=test-x86_64
    812endif
    913TESTS+=sha1# test_path
     
    2529        ./$@ || { rm $@; exit 1; }
    2630
    27 # i386 emulation test (test various opcodes) */
     31# i386/x86_64 emulation test (test various opcodes) */
    2832test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
    2933           test-i386.h test-i386-shift.h test-i386-muldiv.h
    30         $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c \
    31               test-i386-code16.S test-i386-vm86.S -lm
     34        $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ \
     35              test-i386.c test-i386-code16.S test-i386-vm86.S -lm
     36
     37test-x86_64: test-i386.c \
     38           test-i386.h test-i386-shift.h test-i386-muldiv.h
     39        $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c -lm
    3240
    3341ifeq ($(ARCH),i386)
     
    6573# NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
    6674qruncom: qruncom.c ../i386-user/libqemu.a
    67         $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user \
     75        $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
    6876              -o $@ $< -L../i386-user -lqemu -lm
    6977
     
    7583        arm-linux-gcc -Wall -g -O2 -c -o $@ $<
    7684
     85# MIPS test
     86hello-mips: hello-mips.c
     87        mips-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
     88
     89hello-mipsel: hello-mips.c
     90        mipsel-linux-gnu-gcc -nostdlib -static -mno-abicalls -fno-PIC -mabi=32 -Wall -Wextra -g -O2 -o $@ $<
     91
    7792# XXX: find a way to compile easily a test for each arch
    7893test2:
    79         @for arch in i386 arm sparc ppc; do \
     94        @for arch in i386 arm armeb sparc ppc mips mipsel; do \
    8095           ../$${arch}-user/qemu-$${arch} $${arch}/ls -l linux-test.c ; \
    8196        done
    8297
    8398clean:
    84         rm -f *~ *.o test-i386.out test-i386.ref qruncom $(TESTS)
     99        rm -f *~ *.o test-i386.out test-i386.ref \
     100           test-x86_64.log test-x86_64.ref qruncom $(TESTS)
  • trunk/src/recompiler/tests/qruncom.c

    r1 r2426  
    1111#include <sys/mman.h>
    1212#include <signal.h>
     13#include <malloc.h>
    1314
    1415#include "cpu.h"
    1516
    1617//#define SIGTEST
    17 
    18 CPUState *cpu_single_env = NULL;
    1918
    2019void cpu_outb(CPUState *env, int addr, int val)
     
    8786{
    8887    return malloc(size);
     88}
     89
     90void *qemu_mallocz(size_t size)
     91{
     92    void *ptr;
     93    ptr = qemu_malloc(size);
     94    if (!ptr)
     95        return NULL;
     96    memset(ptr, 0, size);
     97    return ptr;
     98}
     99
     100void *qemu_vmalloc(size_t size)
     101{
     102    return memalign(4096, size);
     103}
     104
     105void qemu_vfree(void *ptr)
     106{
     107    free(ptr);
    89108}
    90109
     
    207226
    208227    cpu_x86_load_seg_cache(env, R_CS, seg,
    209                            (uint8_t *)(seg << 4), 0xffff, 0);
     228                           (seg << 4), 0xffff, 0);
    210229    cpu_x86_load_seg_cache(env, R_SS, seg,
    211                            (uint8_t *)(seg << 4), 0xffff, 0);
     230                           (seg << 4), 0xffff, 0);
    212231    cpu_x86_load_seg_cache(env, R_DS, seg,
    213                            (uint8_t *)(seg << 4), 0xffff, 0);
     232                           (seg << 4), 0xffff, 0);
    214233    cpu_x86_load_seg_cache(env, R_ES, seg,
    215                            (uint8_t *)(seg << 4), 0xffff, 0);
     234                           (seg << 4), 0xffff, 0);
    216235    cpu_x86_load_seg_cache(env, R_FS, seg,
    217                            (uint8_t *)(seg << 4), 0xffff, 0);
     236                           (seg << 4), 0xffff, 0);
    218237    cpu_x86_load_seg_cache(env, R_GS, seg,
    219                            (uint8_t *)(seg << 4), 0xffff, 0);
     238                           (seg << 4), 0xffff, 0);
    220239
    221240    /* exception support */
    222     env->idt.base = (void *)idt_table;
     241    env->idt.base = (unsigned long)idt_table;
    223242    env->idt.limit = sizeof(idt_table) - 1;
    224243    set_idt(0, 0);
     
    266285            {
    267286                int int_num, ah;
    268                 int_num = *(env->segs[R_CS].base + env->eip + 1);
     287                int_num = *(uint8_t *)(env->segs[R_CS].base + env->eip + 1);
    269288                if (int_num != 0x21)
    270289                    goto unknown_int;
     
    294313                unknown_int:
    295314                    fprintf(stderr, "unsupported int 0x%02x\n", int_num);
    296                     cpu_dump_state(env, stderr, 0);
     315                    cpu_dump_state(env, stderr, fprintf, 0);
    297316                    //                    exit(1);
    298317                }
     
    302321        default:
    303322            fprintf(stderr, "unhandled cpu_exec return code (0x%x)\n", ret);
    304             cpu_dump_state(env, stderr, 0);
     323            cpu_dump_state(env, stderr, fprintf, 0);
    305324            exit(1);
    306325        }
  • trunk/src/recompiler/tests/test-i386-code16.S

    r1 r2426  
    7878
    7979code16_end:
    80 
    81 
    82 /* other 32 bits tests */
    83         .code32
    84 
    85         .globl func_lret32
    86 func_lret32:
    87         movl $0x87654321, %eax
    88         lret
    89 
    90         .globl func_iret32
    91 func_iret32:
    92         movl $0xabcd4321, %eax
    93         iret
    94 
    95                
    96 
    97        
  • trunk/src/recompiler/tests/test-i386-muldiv.h

    r1 r2426  
    11
    2 void glue(glue(test_, OP), b)(int op0, int op1)
     2void glue(glue(test_, OP), b)(long op0, long op1)
    33{
    4     int res, s1, s0, flags;
     4    long res, s1, s0, flags;
    55    s0 = op0;
    66    s1 = op1;
     
    1111         stringify(OP)"b %b2\n\t"
    1212         "pushf\n\t"
    13          "popl %1\n\t"
     13         "pop %1\n\t"
    1414         : "=a" (res), "=g" (flags)
    1515         : "q" (s1), "0" (res), "1" (flags));
    16     printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
     16    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
    1717           stringify(OP) "b", s0, s1, res, flags & CC_MASK);
    1818}
    1919
    20 void glue(glue(test_, OP), w)(int op0h, int op0, int op1)
     20void glue(glue(test_, OP), w)(long op0h, long op0, long op1)
    2121{
    22     int res, s1, flags, resh;
     22    long res, s1, flags, resh;
    2323    s1 = op1;
    2424    resh = op0h;
     
    2929         stringify(OP) "w %w3\n\t"
    3030         "pushf\n\t"
    31          "popl %1\n\t"
     31         "pop %1\n\t"
    3232         : "=a" (res), "=g" (flags), "=d" (resh)
    3333         : "q" (s1), "0" (res), "1" (flags), "2" (resh));
    34     printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n",
     34    printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
    3535           stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK);
    3636}
    3737
    38 void glue(glue(test_, OP), l)(int op0h, int op0, int op1)
     38void glue(glue(test_, OP), l)(long op0h, long op0, long op1)
    3939{
    40     int res, s1, flags, resh;
     40    long res, s1, flags, resh;
    4141    s1 = op1;
    4242    resh = op0h;
     
    4545    asm ("push %5\n\t"
    4646         "popf\n\t"
    47          stringify(OP) "l %3\n\t"
     47         stringify(OP) "l %k3\n\t"
    4848         "pushf\n\t"
    49          "popl %1\n\t"
     49         "pop %1\n\t"
    5050         : "=a" (res), "=g" (flags), "=d" (resh)
    5151         : "q" (s1), "0" (res), "1" (flags), "2" (resh));
    52     printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n",
     52    printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
    5353           stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK);
    5454}
    5555
     56#if defined(__x86_64__)
     57void glue(glue(test_, OP), q)(long op0h, long op0, long op1)
     58{
     59    long res, s1, flags, resh;
     60    s1 = op1;
     61    resh = op0h;
     62    res = op0;
     63    flags = 0;
     64    asm ("push %5\n\t"
     65         "popf\n\t"
     66         stringify(OP) "q %3\n\t"
     67         "pushf\n\t"
     68         "pop %1\n\t"
     69         : "=a" (res), "=g" (flags), "=d" (resh)
     70         : "q" (s1), "0" (res), "1" (flags), "2" (resh));
     71    printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
     72           stringify(OP) "q", op0h, op0, s1, resh, res, flags & CC_MASK);
     73}
     74#endif
     75
    5676#undef OP
  • trunk/src/recompiler/tests/test-i386-shift.h

    r1 r2426  
    11
    22#define exec_op glue(exec_, OP)
     3#define exec_opq glue(glue(exec_, OP), q)
    34#define exec_opl glue(glue(exec_, OP), l)
    45#define exec_opw glue(glue(exec_, OP), w)
     
    89
    910#ifdef OP_NOBYTE
    10 #define EXECSHIFT(size, res, s1, s2, flags) \
     11#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
    1112    asm ("push %4\n\t"\
    1213         "popf\n\t"\
    13          stringify(OP) size " %" size "2, %" size "0\n\t" \
     14         stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \
    1415         "pushf\n\t"\
    15          "popl %1\n\t"\
     16         "pop %1\n\t"\
    1617         : "=g" (res), "=g" (flags)\
    1718         : "r" (s1), "0" (res), "1" (flags));
    1819#else
    19 #define EXECSHIFT(size, res, s1, s2, flags) \
     20#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
    2021    asm ("push %4\n\t"\
    2122         "popf\n\t"\
    22          stringify(OP) size " %%cl, %" size "0\n\t" \
     23         stringify(OP) size " %%cl, %" rsize "0\n\t" \
    2324         "pushf\n\t"\
    24          "popl %1\n\t"\
     25         "pop %1\n\t"\
    2526         : "=q" (res), "=g" (flags)\
    2627         : "c" (s1), "0" (res), "1" (flags));
    2728#endif
    2829
    29 void exec_opl(int s2, int s0, int s1, int iflags)
     30#if defined(__x86_64__)
     31void exec_opq(long s2, long s0, long s1, long iflags)
    3032{
    31     int res, flags;
     33    long res, flags;
    3234    res = s0;
    3335    flags = iflags;
    34     EXECSHIFT("", res, s1, s2, flags);
     36    EXECSHIFT("q", "", res, s1, s2, flags);
    3537    /* overflow is undefined if count != 1 */
    3638    if (s1 != 1)
    3739      flags &= ~CC_O;
    38     printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
     40    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
     41           stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK);
     42}
     43#endif
     44
     45void exec_opl(long s2, long s0, long s1, long iflags)
     46{
     47    long res, flags;
     48    res = s0;
     49    flags = iflags;
     50    EXECSHIFT("l", "k", res, s1, s2, flags);
     51    /* overflow is undefined if count != 1 */
     52    if (s1 != 1)
     53      flags &= ~CC_O;
     54    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
    3955           stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
    4056}
    4157
    42 void exec_opw(int s2, int s0, int s1, int iflags)
     58void exec_opw(long s2, long s0, long s1, long iflags)
    4359{
    44     int res, flags;
     60    long res, flags;
    4561    res = s0;
    4662    flags = iflags;
    47     EXECSHIFT("w", res, s1, s2, flags);
     63    EXECSHIFT("w", "w", res, s1, s2, flags);
    4864    /* overflow is undefined if count != 1 */
    4965    if (s1 != 1)
    5066      flags &= ~CC_O;
    51     printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
     67    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
    5268           stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
    5369}
    5470
    5571#else
    56 #define EXECSHIFT(size, res, s1, s2, flags) \
     72#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
    5773    asm ("push %4\n\t"\
    5874         "popf\n\t"\
    59          stringify(OP) size " %%cl, %" size "5, %" size "0\n\t" \
     75         stringify(OP) size " %%cl, %" rsize "5, %" rsize "0\n\t" \
    6076         "pushf\n\t"\
    61          "popl %1\n\t"\
     77         "pop %1\n\t"\
    6278         : "=g" (res), "=g" (flags)\
    6379         : "c" (s1), "0" (res), "1" (flags), "r" (s2));
    6480
    65 void exec_opl(int s2, int s0, int s1, int iflags)
     81#if defined(__x86_64__)
     82void exec_opq(long s2, long s0, long s1, long iflags)
    6683{
    67     int res, flags;
     84    long res, flags;
    6885    res = s0;
    6986    flags = iflags;
    70     EXECSHIFT("", res, s1, s2, flags);
     87    EXECSHIFT("q", "", res, s1, s2, flags);
    7188    /* overflow is undefined if count != 1 */
    7289    if (s1 != 1)
    7390      flags &= ~CC_O;
    74     printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n",
     91    printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
     92           stringify(OP) "q", s0, s2, s1, res, iflags, flags & CC_MASK);
     93}
     94#endif
     95
     96void exec_opl(long s2, long s0, long s1, long iflags)
     97{
     98    long res, flags;
     99    res = s0;
     100    flags = iflags;
     101    EXECSHIFT("l", "k", res, s1, s2, flags);
     102    /* overflow is undefined if count != 1 */
     103    if (s1 != 1)
     104      flags &= ~CC_O;
     105    printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
    75106           stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
    76107}
    77108
    78 void exec_opw(int s2, int s0, int s1, int iflags)
     109void exec_opw(long s2, long s0, long s1, long iflags)
    79110{
    80     int res, flags;
     111    long res, flags;
    81112    res = s0;
    82113    flags = iflags;
    83     EXECSHIFT("w", res, s1, s2, flags);
     114    EXECSHIFT("w", "w", res, s1, s2, flags);
    84115    /* overflow is undefined if count != 1 */
    85116    if (s1 != 1)
    86117      flags &= ~CC_O;
    87     printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n",
     118    printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
    88119           stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
    89120}
     
    92123
    93124#ifndef OP_NOBYTE
    94 void exec_opb(int s0, int s1, int iflags)
     125void exec_opb(long s0, long s1, long iflags)
    95126{
    96     int res, flags;
     127    long res, flags;
    97128    res = s0;
    98129    flags = iflags;
    99     EXECSHIFT("b", res, s1, 0, flags);
     130    EXECSHIFT("b", "b", res, s1, 0, flags);
    100131    /* overflow is undefined if count != 1 */
    101132    if (s1 != 1)
    102133      flags &= ~CC_O;
    103     printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
     134    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
    104135           stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
    105136}
    106137#endif
    107138
    108 void exec_op(int s2, int s0, int s1)
     139void exec_op(long s2, long s0, long s1)
    109140{
     141    s2 = i2l(s2);
     142    s0 = i2l(s0);
     143#if defined(__x86_64__)
     144    exec_opq(s2, s0, s1, 0);
     145#endif
    110146    exec_opl(s2, s0, s1, 0);
    111147#ifdef OP_SHIFTD
     
    119155#endif
    120156#ifdef OP_CC
     157#if defined(__x86_64__)
     158    exec_opq(s2, s0, s1, CC_C);
     159#endif
    121160    exec_opl(s2, s0, s1, CC_C);
    122161    exec_opw(s2, s0, s1, CC_C);
     
    127166void glue(test_, OP)(void)
    128167{
    129     int i;
    130     for(i = 0; i < 32; i++)
     168    int i, n;
     169#if defined(__x86_64__)
     170    n = 64;
     171#else
     172    n = 32;
     173#endif
     174    for(i = 0; i < n; i++)
    131175        exec_op(0x21ad3d34, 0x12345678, i);
    132     for(i = 0; i < 32; i++)
    133         exec_op(0x813f3421, 0x82345678, i);
     176    for(i = 0; i < n; i++)
     177        exec_op(0x813f3421, 0x82345679, i);
    134178}
    135179
  • trunk/src/recompiler/tests/test-i386.c

    r1 r2426  
    2929#include <sys/ucontext.h>
    3030#include <sys/mman.h>
    31 #include <asm/vm86.h>
    32 
     31
     32#if !defined(__x86_64__)
     33#define TEST_VM86
     34#define TEST_SEGS
     35#endif
     36//#define LINUX_VM86_IOPL_FIX
     37//#define TEST_P4_FLAGS
     38#if defined(__x86_64__)
     39#define TEST_SSE
     40#define TEST_CMOV  1
     41#define TEST_FCOMI 1
     42#else
     43//#define TEST_SSE
    3344#define TEST_CMOV  0
    3445#define TEST_FCOMI 0
    35 //#define LINUX_VM86_IOPL_FIX
    36 //#define TEST_P4_FLAGS
     46#endif
     47
     48#if defined(__x86_64__)
     49#define FMT64X "%016lx"
     50#define FMTLX "%016lx"
     51#define X86_64_ONLY(x) x
     52#else
     53#define FMT64X "%016" PRIx64
     54#define FMTLX "%08lx"
     55#define X86_64_ONLY(x)
     56#endif
     57
     58#ifdef TEST_VM86
     59#include <asm/vm86.h>
     60#endif
    3761
    3862#define xglue(x, y) x ## y
     
    4872#define CC_O    0x0800
    4973
    50 #define __init_call     __attribute__ ((unused,__section__ (".initcall.init")))
    51 
    52 static void *call_start __init_call = NULL;
     74#define __init_call     __attribute__ ((unused,__section__ ("initcall")))
    5375
    5476#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
     77
     78#if defined(__x86_64__)
     79static inline long i2l(long v)
     80{
     81    return v | ((v ^ 0xabcd) << 32);
     82}
     83#else
     84static inline long i2l(long v)
     85{
     86    return v;
     87}
     88#endif
    5589
    5690#define OP add
     
    157191
    158192/* lea test (modrm support) */
    159 #define TEST_LEA(STR)\
    160 {\
    161     asm("leal " STR ", %0"\
     193#define TEST_LEAQ(STR)\
     194{\
     195    asm("lea " STR ", %0"\
    162196        : "=r" (res)\
    163197        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
    164     printf("lea %s = %08x\n", STR, res);\
     198    printf("lea %s = " FMTLX "\n", STR, res);\
     199}
     200
     201#define TEST_LEA(STR)\
     202{\
     203    asm("lea " STR ", %0"\
     204        : "=r" (res)\
     205        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
     206    printf("lea %s = " FMTLX "\n", STR, res);\
    165207}
    166208
     
    170212        : "=wq" (res)\
    171213        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
    172     printf("lea %s = %08x\n", STR, res);\
     214    printf("lea %s = %08lx\n", STR, res);\
    173215}
    174216
     
    176218void test_lea(void)
    177219{
    178     int eax, ebx, ecx, edx, esi, edi, res;
    179     eax = 0x0001;
    180     ebx = 0x0002;
    181     ecx = 0x0004;
    182     edx = 0x0008;
    183     esi = 0x0010;
    184     edi = 0x0020;
     220    long eax, ebx, ecx, edx, esi, edi, res;
     221    eax = i2l(0x0001);
     222    ebx = i2l(0x0002);
     223    ecx = i2l(0x0004);
     224    edx = i2l(0x0008);
     225    esi = i2l(0x0010);
     226    edi = i2l(0x0020);
    185227
    186228    TEST_LEA("0x4000");
     
    238280    TEST_LEA("0x4000(%%esi, %%ecx, 8)");
    239281
     282#if defined(__x86_64__)
     283    TEST_LEAQ("0x4000");
     284    TEST_LEAQ("0x4000(%%rip)");
     285
     286    TEST_LEAQ("(%%rax)");
     287    TEST_LEAQ("(%%rbx)");
     288    TEST_LEAQ("(%%rcx)");
     289    TEST_LEAQ("(%%rdx)");
     290    TEST_LEAQ("(%%rsi)");
     291    TEST_LEAQ("(%%rdi)");
     292
     293    TEST_LEAQ("0x40(%%rax)");
     294    TEST_LEAQ("0x40(%%rbx)");
     295    TEST_LEAQ("0x40(%%rcx)");
     296    TEST_LEAQ("0x40(%%rdx)");
     297    TEST_LEAQ("0x40(%%rsi)");
     298    TEST_LEAQ("0x40(%%rdi)");
     299
     300    TEST_LEAQ("0x4000(%%rax)");
     301    TEST_LEAQ("0x4000(%%rbx)");
     302    TEST_LEAQ("0x4000(%%rcx)");
     303    TEST_LEAQ("0x4000(%%rdx)");
     304    TEST_LEAQ("0x4000(%%rsi)");
     305    TEST_LEAQ("0x4000(%%rdi)");
     306
     307    TEST_LEAQ("(%%rax, %%rcx)");
     308    TEST_LEAQ("(%%rbx, %%rdx)");
     309    TEST_LEAQ("(%%rcx, %%rcx)");
     310    TEST_LEAQ("(%%rdx, %%rcx)");
     311    TEST_LEAQ("(%%rsi, %%rcx)");
     312    TEST_LEAQ("(%%rdi, %%rcx)");
     313
     314    TEST_LEAQ("0x40(%%rax, %%rcx)");
     315    TEST_LEAQ("0x4000(%%rbx, %%rdx)");
     316
     317    TEST_LEAQ("(%%rcx, %%rcx, 2)");
     318    TEST_LEAQ("(%%rdx, %%rcx, 4)");
     319    TEST_LEAQ("(%%rsi, %%rcx, 8)");
     320
     321    TEST_LEAQ("(,%%rax, 2)");
     322    TEST_LEAQ("(,%%rbx, 4)");
     323    TEST_LEAQ("(,%%rcx, 8)");
     324
     325    TEST_LEAQ("0x40(,%%rax, 2)");
     326    TEST_LEAQ("0x40(,%%rbx, 4)");
     327    TEST_LEAQ("0x40(,%%rcx, 8)");
     328
     329
     330    TEST_LEAQ("-10(%%rcx, %%rcx, 2)");
     331    TEST_LEAQ("-10(%%rdx, %%rcx, 4)");
     332    TEST_LEAQ("-10(%%rsi, %%rcx, 8)");
     333
     334    TEST_LEAQ("0x4000(%%rcx, %%rcx, 2)");
     335    TEST_LEAQ("0x4000(%%rdx, %%rcx, 4)");
     336    TEST_LEAQ("0x4000(%%rsi, %%rcx, 8)");
     337#else
    240338    /* limited 16 bit addressing test */
    241339    TEST_LEA16("0x4000");
     
    254352    TEST_LEA16("0x4000(%%bx,%%si)");
    255353    TEST_LEA16("0x4000(%%bx,%%di)");
     354#endif
    256355}
    257356
     
    275374    printf("%-10s %d\n", "set" JCC, res);\
    276375 if (TEST_CMOV) {\
    277     asm("movl $0x12345678, %0\n\t"\
    278         "cmpl %2, %1\n\t"\
    279         "cmov" JCC "l %3, %0\n\t"\
     376    long val = i2l(1);\
     377    long res = i2l(0x12345678);\
     378X86_64_ONLY(\
     379    asm("cmpl %2, %1\n\t"\
     380        "cmov" JCC "q %3, %0\n\t"\
    280381        : "=r" (res)\
    281         : "r" (v1), "r" (v2), "m" (1));\
    282         printf("%-10s R=0x%08x\n", "cmov" JCC "l", res);\
    283     asm("movl $0x12345678, %0\n\t"\
    284         "cmpl %2, %1\n\t"\
     382        : "r" (v1), "r" (v2), "m" (val), "0" (res));\
     383        printf("%-10s R=" FMTLX "\n", "cmov" JCC "q", res);)\
     384    asm("cmpl %2, %1\n\t"\
     385        "cmov" JCC "l %k3, %k0\n\t"\
     386        : "=r" (res)\
     387        : "r" (v1), "r" (v2), "m" (val), "0" (res));\
     388        printf("%-10s R=" FMTLX "\n", "cmov" JCC "l", res);\
     389    asm("cmpl %2, %1\n\t"\
    285390        "cmov" JCC "w %w3, %w0\n\t"\
    286391        : "=r" (res)\
    287         : "r" (v1), "r" (v2), "r" (1));\
    288         printf("%-10s R=0x%08x\n", "cmov" JCC "w", res);\
     392        : "r" (v1), "r" (v2), "r" (1), "0" (res));\
     393        printf("%-10s R=" FMTLX "\n", "cmov" JCC "w", res);\
    289394 } \
    290395}
     
    366471#include "test-i386-muldiv.h"
    367472
    368 void test_imulw2(int op0, int op1)
    369 {
    370     int res, s1, s0, flags;
     473void test_imulw2(long op0, long op1)
     474{
     475    long res, s1, s0, flags;
    371476    s0 = op0;
    372477    s1 = op1;
    373478    res = s0;
    374479    flags = 0;
    375     asm ("push %4\n\t"
     480    asm volatile ("push %4\n\t"
    376481         "popf\n\t"
    377482         "imulw %w2, %w0\n\t"
    378483         "pushf\n\t"
    379          "popl %1\n\t"
     484         "pop %1\n\t"
    380485         : "=q" (res), "=g" (flags)
    381486         : "q" (s1), "0" (res), "1" (flags));
    382     printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
     487    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
    383488           "imulw", s0, s1, res, flags & CC_MASK);
    384489}
    385490
    386 void test_imull2(int op0, int op1)
    387 {
    388     int res, s1, s0, flags;
     491void test_imull2(long op0, long op1)
     492{
     493    long res, s1, s0, flags;
    389494    s0 = op0;
    390495    s1 = op1;
    391496    res = s0;
    392497    flags = 0;
    393     asm ("push %4\n\t"
     498    asm volatile ("push %4\n\t"
    394499         "popf\n\t"
    395          "imull %2, %0\n\t"
     500         "imull %k2, %k0\n\t"
    396501         "pushf\n\t"
    397          "popl %1\n\t"
     502         "pop %1\n\t"
    398503         : "=q" (res), "=g" (flags)
    399504         : "q" (s1), "0" (res), "1" (flags));
    400     printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
     505    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
    401506           "imull", s0, s1, res, flags & CC_MASK);
    402507}
    403508
    404 #define TEST_IMUL_IM(size, size1, op0, op1)\
    405 {\
    406     int res, flags;\
     509#if defined(__x86_64__)
     510void test_imulq2(long op0, long op1)
     511{
     512    long res, s1, s0, flags;
     513    s0 = op0;
     514    s1 = op1;
     515    res = s0;
     516    flags = 0;
     517    asm volatile ("push %4\n\t"
     518         "popf\n\t"
     519         "imulq %2, %0\n\t"
     520         "pushf\n\t"
     521         "pop %1\n\t"
     522         : "=q" (res), "=g" (flags)
     523         : "q" (s1), "0" (res), "1" (flags));
     524    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
     525           "imulq", s0, s1, res, flags & CC_MASK);
     526}
     527#endif
     528
     529#define TEST_IMUL_IM(size, rsize, op0, op1)\
     530{\
     531    long res, flags, s1;\
    407532    flags = 0;\
    408533    res = 0;\
    409     asm ("push %3\n\t"\
     534    s1 = op1;\
     535    asm volatile ("push %3\n\t"\
    410536         "popf\n\t"\
    411          "imul" size " $" #op0 ", %" size1 "2, %" size1 "0\n\t" \
     537         "imul" size " $" #op0 ", %" rsize "2, %" rsize "0\n\t" \
    412538         "pushf\n\t"\
    413          "popl %1\n\t"\
     539         "pop %1\n\t"\
    414540         : "=r" (res), "=g" (flags)\
    415          : "r" (op1), "1" (flags), "0" (res));\
    416     printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",\
    417            "imul" size, op0, op1, res, flags & CC_MASK);\
     541         : "r" (s1), "1" (flags), "0" (res));\
     542    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",\
     543           "imul" size " im", (long)op0, (long)op1, res, flags & CC_MASK);\
    418544}
    419545
     
    475601    TEST_IMUL_IM("w", "w", 0x7fff, 0x1000);
    476602
    477     TEST_IMUL_IM("l", "", 45, 0x1234);
    478     TEST_IMUL_IM("l", "", -45, 23);
    479     TEST_IMUL_IM("l", "", 0x8000, 0x80000000);
    480     TEST_IMUL_IM("l", "", 0x7fff, 0x1000);
     603    TEST_IMUL_IM("l", "k", 45, 0x1234);
     604    TEST_IMUL_IM("l", "k", -45, 23);
     605    TEST_IMUL_IM("l", "k", 0x8000, 0x80000000);
     606    TEST_IMUL_IM("l", "k", 0x7fff, 0x1000);
    481607
    482608    test_idivb(0x12341678, 0x127e);
     
    507633    test_divl(0, 0x80000000, -1);
    508634    test_divl(0x12343, 0x12345678, 0x81234567);
     635
     636#if defined(__x86_64__)
     637    test_imulq(0, 0x1234001d1234001d, 45);
     638    test_imulq(0, 23, -45);
     639    test_imulq(0, 0x8000000000000000, 0x8000000000000000);
     640    test_imulq(0, 0x100000000, 0x100000000);
     641
     642    test_mulq(0, 0x1234001d1234001d, 45);
     643    test_mulq(0, 23, -45);
     644    test_mulq(0, 0x8000000000000000, 0x8000000000000000);
     645    test_mulq(0, 0x100000000, 0x100000000);
     646
     647    test_imulq2(0x1234001d1234001d, 45);
     648    test_imulq2(23, -45);
     649    test_imulq2(0x8000000000000000, 0x8000000000000000);
     650    test_imulq2(0x100000000, 0x100000000);
     651
     652    TEST_IMUL_IM("q", "", 45, 0x12341234);
     653    TEST_IMUL_IM("q", "", -45, 23);
     654    TEST_IMUL_IM("q", "", 0x8000, 0x8000000000000000);
     655    TEST_IMUL_IM("q", "", 0x7fff, 0x10000000);
     656
     657    test_idivq(0, 0x12345678abcdef, 12347);
     658    test_idivq(0, -233223, -45);
     659    test_idivq(0, 0x8000000000000000, -1);
     660    test_idivq(0x12343, 0x12345678, 0x81234567);
     661
     662    test_divq(0, 0x12345678abcdef, 12347);
     663    test_divq(0, -233223, -45);
     664    test_divq(0, 0x8000000000000000, -1);
     665    test_divq(0x12343, 0x12345678, 0x81234567);
     666#endif
    509667}
    510668
    511669#define TEST_BSX(op, size, op0)\
    512670{\
    513     int res, val, resz;\
     671    long res, val, resz;\
    514672    val = op0;\
    515     asm("xorl %1, %1\n"\
    516         "movl $0x12345678, %0\n"\
     673    asm("xor %1, %1\n"\
     674        "mov $0x12345678, %0\n"\
    517675        #op " %" size "2, %" size "0 ; setz %b1" \
    518676        : "=r" (res), "=q" (resz)\
    519677        : "g" (val));\
    520     printf("%-10s A=%08x R=%08x %d\n", #op, val, res, resz);\
     678    printf("%-10s A=" FMTLX " R=" FMTLX " %ld\n", #op, val, res, resz);\
    521679}
    522680
     
    525683    TEST_BSX(bsrw, "w", 0);
    526684    TEST_BSX(bsrw, "w", 0x12340128);
    527     TEST_BSX(bsrl, "", 0);
    528     TEST_BSX(bsrl, "", 0x00340128);
    529685    TEST_BSX(bsfw, "w", 0);
    530686    TEST_BSX(bsfw, "w", 0x12340128);
    531     TEST_BSX(bsfl, "", 0);
    532     TEST_BSX(bsfl, "", 0x00340128);
     687    TEST_BSX(bsrl, "k", 0);
     688    TEST_BSX(bsrl, "k", 0x00340128);
     689    TEST_BSX(bsfl, "k", 0);
     690    TEST_BSX(bsfl, "k", 0x00340128);
     691#if defined(__x86_64__)
     692    TEST_BSX(bsrq, "", 0);
     693    TEST_BSX(bsrq, "", 0x003401281234);
     694    TEST_BSX(bsfq, "", 0);
     695    TEST_BSX(bsfq, "", 0x003401281234);
     696#endif
    533697}
    534698
    535699/**********************************************/
     700
     701union float64u {
     702    double d;
     703    uint64_t l;
     704};
     705
     706union float64u q_nan = { .l = 0xFFF8000000000000 };
     707union float64u s_nan = { .l = 0xFFF0000000000000 };
    536708
    537709void test_fops(double a, double b)
     
    556728}
    557729
     730void fpu_clear_exceptions(void)
     731{
     732    struct __attribute__((packed)) {
     733        uint16_t fpuc;
     734        uint16_t dummy1;
     735        uint16_t fpus;
     736        uint16_t dummy2;
     737        uint16_t fptag;
     738        uint16_t dummy3;
     739        uint32_t ignored[4];
     740        long double fpregs[8];
     741    } float_env32;
     742   
     743    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
     744    float_env32.fpus &= ~0x7f;
     745    asm volatile ("fldenv %0\n" : : "m" (float_env32));
     746}
     747
     748/* XXX: display exception bits when supported */
     749#define FPUS_EMASK 0x0000
     750//#define FPUS_EMASK 0x007f
     751
    558752void test_fcmp(double a, double b)
    559753{
    560     printf("(%f<%f)=%d\n",
    561            a, b, a < b);
    562     printf("(%f<=%f)=%d\n",
    563            a, b, a <= b);
    564     printf("(%f==%f)=%d\n",
    565            a, b, a == b);
    566     printf("(%f>%f)=%d\n",
    567            a, b, a > b);
    568     printf("(%f<=%f)=%d\n",
    569            a, b, a >= b);
     754    long eflags, fpus;
     755
     756    fpu_clear_exceptions();
     757    asm("fcom %2\n"
     758        "fstsw %%ax\n"
     759        : "=a" (fpus)
     760        : "t" (a), "u" (b));
     761    printf("fcom(%f %f)=%04lx \n",
     762           a, b, fpus & (0x4500 | FPUS_EMASK));
     763    fpu_clear_exceptions();
     764    asm("fucom %2\n"
     765        "fstsw %%ax\n"
     766        : "=a" (fpus)
     767        : "t" (a), "u" (b));
     768    printf("fucom(%f %f)=%04lx\n",
     769           a, b, fpus & (0x4500 | FPUS_EMASK));
    570770    if (TEST_FCOMI) {
    571         unsigned int eflags;
    572771        /* test f(u)comi instruction */
    573         asm("fcomi %2, %1\n"
     772        fpu_clear_exceptions();
     773        asm("fcomi %3, %2\n"
     774            "fstsw %%ax\n"
    574775            "pushf\n"
    575776            "pop %0\n"
    576             : "=r" (eflags)
     777            : "=r" (eflags), "=a" (fpus)
    577778            : "t" (a), "u" (b));
    578         printf("fcomi(%f %f)=%08x\n", a, b, eflags & (CC_Z | CC_P | CC_C));
    579     }
     779        printf("fcomi(%f %f)=%04lx %02lx\n",
     780               a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
     781        fpu_clear_exceptions();
     782        asm("fucomi %3, %2\n"
     783            "fstsw %%ax\n"
     784            "pushf\n"
     785            "pop %0\n"
     786            : "=r" (eflags), "=a" (fpus)
     787            : "t" (a), "u" (b));
     788        printf("fucomi(%f %f)=%04lx %02lx\n",
     789               a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));
     790    }
     791    fpu_clear_exceptions();
     792    asm volatile("fxam\n"
     793                 "fstsw %%ax\n"
     794                 : "=a" (fpus)
     795                 : "t" (a));
     796    printf("fxam(%f)=%04lx\n", a, fpus & 0x4700);
     797    fpu_clear_exceptions();
    580798}
    581799
     
    595813    printf("(float)%f = %f\n", a, fa);
    596814    printf("(long double)%f = %Lf\n", a, la);
    597     printf("a=%016Lx\n", *(long long *)&a);
    598     printf("la=%016Lx %04x\n", *(long long *)&la,
     815    printf("a=" FMT64X "\n", *(uint64_t *)&a);
     816    printf("la=" FMT64X " %04x\n", *(uint64_t *)&la,
    599817           *(unsigned short *)((char *)(&la) + 8));
    600818
     
    610828        printf("(short)a = %d\n", wa);
    611829        printf("(int)a = %d\n", ia);
    612         printf("(int64_t)a = %Ld\n", lla);
     830        printf("(int64_t)a = " FMT64X "\n", lla);
    613831        printf("rint(a) = %f\n", ra);
    614832    }
     
    647865    for(i=0;i<5;i++)\
    648866        asm volatile ("fldl %0" : : "m" (dtab[i]));\
    649     asm(save " %0\n" : : "m" (*(env)));\
    650     asm(restore " %0\n": : "m" (*(env)));\
     867    asm volatile (save " %0\n" : : "m" (*(env)));\
     868    asm volatile (restore " %0\n": : "m" (*(env)));\
    651869    for(i=0;i<5;i++)\
    652870        asm volatile ("fstpl %0" : "=m" (rtab[i]));\
     
    708926        : "=t" (res)\
    709927        : "0" (a), "u" (b), "g" (eflags));\
    710     printf("fcmov%s eflags=0x%04x-> %f\n", \
    711            CC, eflags, res);\
     928    printf("fcmov%s eflags=0x%04lx-> %f\n", \
     929           CC, (long)eflags, res);\
    712930}
    713931
     
    715933{
    716934    double a, b;
    717     int eflags, i;
     935    long eflags, i;
    718936
    719937    a = 1.0;
     
    745963    test_fcmp(2, 2);
    746964    test_fcmp(2, 3);
     965    test_fcmp(2, q_nan.d);
     966    test_fcmp(q_nan.d, -1);
     967    test_fcmp(-1.0/0.0, -1);
     968    test_fcmp(1.0/0.0, -1);
    747969    test_fcvt(0.5);
    748970    test_fcvt(-0.5);
     
    751973    test_fcvt(32768);
    752974    test_fcvt(-1e20);
     975    test_fcvt(-1.0/0.0);
     976    test_fcvt(1.0/0.0);
     977    test_fcvt(q_nan.d);
    753978    test_fconst();
    754979    test_fbcd(1234567890123456);
     
    761986
    762987/**********************************************/
     988#if !defined(__x86_64__)
    763989
    764990#define TEST_BCD(op, op0, cc_in, cc_mask)\
     
    771997         #op "\n\t"\
    772998         "pushf\n\t"\
    773          "popl %1\n\t"\
     999         "pop %1\n\t"\
    7741000        : "=a" (res), "=g" (flags)\
    7751001        : "0" (res), "1" (flags));\
     
    8291055    TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
    8301056}
     1057#endif
    8311058
    8321059#define TEST_XCHG(op, size, opconst)\
    8331060{\
    834     int op0, op1;\
    835     op0 = 0x12345678;\
    836     op1 = 0xfbca7654;\
     1061    long op0, op1;\
     1062    op0 = i2l(0x12345678);\
     1063    op1 = i2l(0xfbca7654);\
    8371064    asm(#op " %" size "0, %" size "1" \
    8381065        : "=q" (op0), opconst (op1) \
    8391066        : "0" (op0), "1" (op1));\
    840     printf("%-10s A=%08x B=%08x\n",\
     1067    printf("%-10s A=" FMTLX " B=" FMTLX "\n",\
    8411068           #op, op0, op1);\
    8421069}
     
    8441071#define TEST_CMPXCHG(op, size, opconst, eax)\
    8451072{\
    846     int op0, op1;\
    847     op0 = 0x12345678;\
    848     op1 = 0xfbca7654;\
     1073    long op0, op1, op2;\
     1074    op0 = i2l(0x12345678);\
     1075    op1 = i2l(0xfbca7654);\
     1076    op2 = i2l(eax);\
    8491077    asm(#op " %" size "0, %" size "1" \
    8501078        : "=q" (op0), opconst (op1) \
    851         : "0" (op0), "1" (op1), "a" (eax));\
    852     printf("%-10s EAX=%08x A=%08x C=%08x\n",\
    853            #op, eax, op0, op1);\
     1079        : "0" (op0), "1" (op1), "a" (op2));\
     1080    printf("%-10s EAX=" FMTLX " A=" FMTLX " C=" FMTLX "\n",\
     1081           #op, op2, op0, op1);\
    8541082}
    8551083
    8561084void test_xchg(void)
    8571085{
    858     TEST_XCHG(xchgl, "", "=q");
     1086#if defined(__x86_64__)
     1087    TEST_XCHG(xchgq, "", "=q");
     1088#endif
     1089    TEST_XCHG(xchgl, "k", "=q");
    8591090    TEST_XCHG(xchgw, "w", "=q");
    8601091    TEST_XCHG(xchgb, "b", "=q");
    8611092
    862     TEST_XCHG(xchgl, "", "=m");
     1093#if defined(__x86_64__)
     1094    TEST_XCHG(xchgq, "", "=m");
     1095#endif
     1096    TEST_XCHG(xchgl, "k", "=m");
    8631097    TEST_XCHG(xchgw, "w", "=m");
    8641098    TEST_XCHG(xchgb, "b", "=m");
    8651099
    866     TEST_XCHG(xaddl, "", "=q");
     1100#if defined(__x86_64__)
     1101    TEST_XCHG(xaddq, "", "=q");
     1102#endif
     1103    TEST_XCHG(xaddl, "k", "=q");
    8671104    TEST_XCHG(xaddw, "w", "=q");
    8681105    TEST_XCHG(xaddb, "b", "=q");
     
    8751112    }
    8761113
    877     TEST_XCHG(xaddl, "", "=m");
     1114#if defined(__x86_64__)
     1115    TEST_XCHG(xaddq, "", "=m");
     1116#endif
     1117    TEST_XCHG(xaddl, "k", "=m");
    8781118    TEST_XCHG(xaddw, "w", "=m");
    8791119    TEST_XCHG(xaddb, "b", "=m");
    8801120
    881     TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654);
     1121#if defined(__x86_64__)
     1122    TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfbca7654);
     1123#endif
     1124    TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfbca7654);
    8821125    TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
    8831126    TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
    8841127
    885     TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc);
     1128#if defined(__x86_64__)
     1129    TEST_CMPXCHG(cmpxchgq, "", "=q", 0xfffefdfc);
     1130#endif
     1131    TEST_CMPXCHG(cmpxchgl, "k", "=q", 0xfffefdfc);
    8861132    TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
    8871133    TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
    8881134
    889     TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654);
     1135#if defined(__x86_64__)
     1136    TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfbca7654);
     1137#endif
     1138    TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfbca7654);
    8901139    TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
    8911140    TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
    8921141
    893     TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc);
     1142#if defined(__x86_64__)
     1143    TEST_CMPXCHG(cmpxchgq, "", "=m", 0xfffefdfc);
     1144#endif
     1145    TEST_CMPXCHG(cmpxchgl, "k", "=m", 0xfffefdfc);
    8941146    TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
    8951147    TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
     
    8971149    {
    8981150        uint64_t op0, op1, op2;
    899         int i, eflags;
     1151        long i, eflags;
    9001152
    9011153        for(i = 0; i < 2; i++) {
     
    9081160            asm("cmpxchg8b %1\n"
    9091161                "pushf\n"
    910                 "popl %2\n"
     1162                "pop %2\n"
    9111163                : "=A" (op0), "=m" (op1), "=g" (eflags)
    9121164                : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
    913             printf("cmpxchg8b: op0=%016llx op1=%016llx CC=%02x\n",
     1165            printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n",
    9141166                    op0, op1, eflags & CC_Z);
    9151167        }
     
    9171169}
    9181170
     1171#ifdef TEST_SEGS
    9191172/**********************************************/
    9201173/* segmentation tests */
     
    9301183#endif
    9311184
     1185#define MK_SEL(n) (((n) << 3) | 7)
     1186
    9321187uint8_t seg_data1[4096];
    9331188uint8_t seg_data2[4096];
    934 
    935 #define MK_SEL(n) (((n) << 3) | 7)
    9361189
    9371190#define TEST_LR(op, size, seg, mask)\
     
    10781331    printf("func3() = 0x%08x\n", res);
    10791332}
    1080 
    1081 extern char func_lret32;
    1082 extern char func_iret32;
     1333#endif
     1334
     1335#if defined(__x86_64__)
     1336asm(".globl func_lret\n"
     1337    "func_lret:\n"
     1338    "movl $0x87654641, %eax\n"
     1339    "lretq\n");
     1340#else
     1341asm(".globl func_lret\n"
     1342    "func_lret:\n"
     1343    "movl $0x87654321, %eax\n"
     1344    "lret\n"
     1345
     1346    ".globl func_iret\n"
     1347    "func_iret:\n"
     1348    "movl $0xabcd4321, %eax\n"
     1349    "iret\n");
     1350#endif
     1351
     1352extern char func_lret;
     1353extern char func_iret;
    10831354
    10841355void test_misc(void)
    10851356{
    10861357    char table[256];
    1087     int res, i;
     1358    long res, i;
    10881359
    10891360    for(i=0;i<256;i++) table[i] = 256 - i;
    10901361    res = 0x12345678;
    10911362    asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
    1092     printf("xlat: EAX=%08x\n", res);
    1093 
    1094     asm volatile ("pushl %%cs ; call %1"
     1363    printf("xlat: EAX=" FMTLX "\n", res);
     1364
     1365#if defined(__x86_64__)
     1366    {
     1367        static struct __attribute__((packed)) {
     1368            uint32_t offset;
     1369            uint16_t seg;
     1370        } desc;
     1371        long cs_sel;
     1372
     1373        asm volatile ("mov %%cs, %0" : "=r" (cs_sel));
     1374
     1375        asm volatile ("push %1\n"
     1376                      "call func_lret\n"
     1377                      : "=a" (res)
     1378                      : "r" (cs_sel) : "memory", "cc");
     1379        printf("func_lret=" FMTLX "\n", res);
     1380
     1381        /* NOTE: we assume that &func_lret < 4GB */
     1382        desc.offset = (long)&func_lret;
     1383        desc.seg = cs_sel;
     1384       
     1385        asm volatile ("xor %%rax, %%rax\n"
     1386                      "rex64 lcall %1\n"
     1387                      : "=a" (res)
     1388                      : "m" (desc)
     1389                      : "memory", "cc");
     1390        printf("func_lret2=" FMTLX "\n", res);
     1391
     1392        asm volatile ("push %2\n"
     1393                      "mov $ 1f, %%rax\n"
     1394                      "push %%rax\n"
     1395                      "ljmp %1\n"
     1396                      "1:\n"
     1397                      : "=a" (res)
     1398                      : "m" (desc), "b" (cs_sel)
     1399                      : "memory", "cc");
     1400        printf("func_lret3=" FMTLX "\n", res);
     1401    }
     1402#else
     1403    asm volatile ("push %%cs ; call %1"
    10951404                  : "=a" (res)
    1096                   : "m" (func_lret32): "memory", "cc");
    1097     printf("func_lret32=%x\n", res);
    1098 
    1099     asm volatile ("pushfl ; pushl %%cs ; call %1"
     1405                  : "m" (func_lret): "memory", "cc");
     1406    printf("func_lret=" FMTLX "\n", res);
     1407
     1408    asm volatile ("pushf ; push %%cs ; call %1"
    11001409                  : "=a" (res)
    1101                   : "m" (func_iret32): "memory", "cc");
    1102     printf("func_iret32=%x\n", res);
    1103 
     1410                  : "m" (func_iret): "memory", "cc");
     1411    printf("func_iret=" FMTLX "\n", res);
     1412#endif
     1413
     1414#if defined(__x86_64__)
     1415    /* specific popl test */
     1416    asm volatile ("push $12345432 ; push $0x9abcdef ; pop (%%rsp) ; pop %0"
     1417                  : "=g" (res));
     1418    printf("popl esp=" FMTLX "\n", res);
     1419#else
    11041420    /* specific popl test */
    11051421    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0"
    11061422                  : "=g" (res));
    1107     printf("popl esp=%x\n", res);
     1423    printf("popl esp=" FMTLX "\n", res);
    11081424
    11091425    /* specific popw test */
    11101426    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0"
    11111427                  : "=g" (res));
    1112     printf("popw esp=%x\n", res);
     1428    printf("popw esp=" FMTLX "\n", res);
     1429#endif
    11131430}
    11141431
     
    11171434#define TEST_STRING1(OP, size, DF, REP)\
    11181435{\
    1119     int esi, edi, eax, ecx, eflags;\
     1436    long esi, edi, eax, ecx, eflags;\
    11201437\
    11211438    esi = (long)(str_buffer + sizeof(str_buffer) / 2);\
    11221439    edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\
    1123     eax = 0x12345678;\
     1440    eax = i2l(0x12345678);\
    11241441    ecx = 17;\
    11251442\
    1126     asm volatile ("pushl $0\n\t"\
     1443    asm volatile ("push $0\n\t"\
    11271444                  "popf\n\t"\
    11281445                  DF "\n\t"\
     
    11301447                  "cld\n\t"\
    11311448                  "pushf\n\t"\
    1132                   "popl %4\n\t"\
     1449                  "pop %4\n\t"\
    11331450                  : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\
    11341451                  : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\
    1135     printf("%-10s ESI=%08x EDI=%08x EAX=%08x ECX=%08x EFL=%04x\n",\
     1452    printf("%-10s ESI=" FMTLX " EDI=" FMTLX " EAX=" FMTLX " ECX=" FMTLX " EFL=%04x\n",\
    11361453           REP #OP size, esi, edi, eax, ecx,\
    1137            eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
     1454           (int)(eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)));\
    11381455}
    11391456
     
    11421459    TEST_STRING1(OP, "w", "", REP);\
    11431460    TEST_STRING1(OP, "l", "", REP);\
     1461    X86_64_ONLY(TEST_STRING1(OP, "q", "", REP));\
    11441462    TEST_STRING1(OP, "b", "std", REP);\
    11451463    TEST_STRING1(OP, "w", "std", REP);\
    1146     TEST_STRING1(OP, "l", "std", REP)
     1464    TEST_STRING1(OP, "l", "std", REP);\
     1465    X86_64_ONLY(TEST_STRING1(OP, "q", "std", REP))
    11471466
    11481467void test_string(void)
     
    11681487}
    11691488
     1489#ifdef TEST_VM86
    11701490/* VM86 test */
    11711491
     
    12981618    munmap(vm86_mem, 0x110000);
    12991619}
     1620#endif
    13001621
    13011622/* exception tests */
    1302 #ifndef REG_EAX
     1623#if defined(__i386__) && !defined(REG_EAX)
    13031624#define REG_EAX EAX
    13041625#define REG_EBX EBX
     
    13151636#endif
    13161637
     1638#if defined(__x86_64__)
     1639#define REG_EIP REG_RIP
     1640#endif
     1641
    13171642jmp_buf jmp_env;
    13181643int v1;
     
    13291654    printf("\n");
    13301655
    1331     printf("trapno=0x%02x err=0x%08x",
    1332            uc->uc_mcontext.gregs[REG_TRAPNO],
    1333            uc->uc_mcontext.gregs[REG_ERR]);
    1334     printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]);
     1656    printf("trapno=" FMTLX " err=" FMTLX,
     1657           (long)uc->uc_mcontext.gregs[REG_TRAPNO],
     1658           (long)uc->uc_mcontext.gregs[REG_ERR]);
     1659    printf(" EIP=" FMTLX, (long)uc->uc_mcontext.gregs[REG_EIP]);
    13351660    printf("\n");
    13361661    longjmp(jmp_env, 1);
     
    13391664void test_exceptions(void)
    13401665{
    1341     struct modify_ldt_ldt_s ldt;
    13421666    struct sigaction act;
    13431667    volatile int val;
     
    13451669    act.sa_sigaction = sig_handler;
    13461670    sigemptyset(&act.sa_mask);
    1347     act.sa_flags = SA_SIGINFO;
     1671    act.sa_flags = SA_SIGINFO | SA_NODEFER;
    13481672    sigaction(SIGFPE, &act, NULL);
    13491673    sigaction(SIGILL, &act, NULL);
     
    13601684    }
    13611685
     1686#if !defined(__x86_64__)
    13621687    printf("BOUND exception:\n");
    13631688    if (setjmp(jmp_env) == 0) {
     
    13671692        asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0]));
    13681693    }
    1369 
     1694#endif
     1695
     1696#ifdef TEST_SEGS
    13701697    printf("segment exceptions:\n");
    13711698    if (setjmp(jmp_env) == 0) {
     
    13801707    }
    13811708
    1382     ldt.entry_number = 1;
    1383     ldt.base_addr = (unsigned long)&seg_data1;
    1384     ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
    1385     ldt.seg_32bit = 1;
    1386     ldt.contents = MODIFY_LDT_CONTENTS_DATA;
    1387     ldt.read_exec_only = 0;
    1388     ldt.limit_in_pages = 1;
    1389     ldt.seg_not_present = 1;
    1390     ldt.useable = 1;
    1391     modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
    1392 
    1393     if (setjmp(jmp_env) == 0) {
    1394         /* segment not present */
    1395         asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
    1396     }
     1709    {
     1710        struct modify_ldt_ldt_s ldt;
     1711        ldt.entry_number = 1;
     1712        ldt.base_addr = (unsigned long)&seg_data1;
     1713        ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
     1714        ldt.seg_32bit = 1;
     1715        ldt.contents = MODIFY_LDT_CONTENTS_DATA;
     1716        ldt.read_exec_only = 0;
     1717        ldt.limit_in_pages = 1;
     1718        ldt.seg_not_present = 1;
     1719        ldt.useable = 1;
     1720        modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
     1721       
     1722        if (setjmp(jmp_env) == 0) {
     1723            /* segment not present */
     1724            asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
     1725        }
     1726    }
     1727#endif
    13971728
    13981729    /* test SEGV reporting */
     
    14581789    }
    14591790
     1791#if !defined(__x86_64__)
    14601792    printf("INTO exception:\n");
    14611793    if (setjmp(jmp_env) == 0) {
     
    14631795        asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
    14641796    }
     1797#endif
    14651798
    14661799    printf("OUTB exception:\n");
     
    15011834}
    15021835
     1836#if !defined(__x86_64__)
    15031837/* specific precise single step test */
    15041838void sig_trap_handler(int sig, siginfo_t *info, void *puc)
    15051839{
    15061840    struct ucontext *uc = puc;
    1507     printf("EIP=0x%08x\n", uc->uc_mcontext.gregs[REG_EIP]);
     1841    printf("EIP=" FMTLX "\n", (long)uc->uc_mcontext.gregs[REG_EIP]);
    15081842}
    15091843
     
    16261960    }
    16271961}
     1962#endif
     1963
     1964long enter_stack[4096];
     1965
     1966#if defined(__x86_64__)
     1967#define RSP "%%rsp"
     1968#define RBP "%%rbp"
     1969#else
     1970#define RSP "%%esp"
     1971#define RBP "%%ebp"
     1972#endif
     1973
     1974#define TEST_ENTER(size, stack_type, level)\
     1975{\
     1976    long esp_save, esp_val, ebp_val, ebp_save, i;\
     1977    stack_type *ptr, *stack_end, *stack_ptr;\
     1978    memset(enter_stack, 0, sizeof(enter_stack));\
     1979    stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\
     1980    ebp_val = (long)stack_ptr;\
     1981    for(i=1;i<=32;i++)\
     1982       *--stack_ptr = i;\
     1983    esp_val = (long)stack_ptr;\
     1984    asm("mov " RSP ", %[esp_save]\n"\
     1985        "mov " RBP ", %[ebp_save]\n"\
     1986        "mov %[esp_val], " RSP "\n"\
     1987        "mov %[ebp_val], " RBP "\n"\
     1988        "enter" size " $8, $" #level "\n"\
     1989        "mov " RSP ", %[esp_val]\n"\
     1990        "mov " RBP ", %[ebp_val]\n"\
     1991        "mov %[esp_save], " RSP "\n"\
     1992        "mov %[ebp_save], " RBP "\n"\
     1993        : [esp_save] "=r" (esp_save),\
     1994        [ebp_save] "=r" (ebp_save),\
     1995        [esp_val] "=r" (esp_val),\
     1996        [ebp_val] "=r" (ebp_val)\
     1997        :  "[esp_val]" (esp_val),\
     1998        "[ebp_val]" (ebp_val));\
     1999    printf("level=%d:\n", level);\
     2000    printf("esp_val=" FMTLX "\n", esp_val - (long)stack_end);\
     2001    printf("ebp_val=" FMTLX "\n", ebp_val - (long)stack_end);\
     2002    for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
     2003        printf(FMTLX "\n", (long)ptr[0]);\
     2004}
     2005
     2006static void test_enter(void)
     2007{
     2008#if defined(__x86_64__)
     2009    TEST_ENTER("q", uint64_t, 0);
     2010    TEST_ENTER("q", uint64_t, 1);
     2011    TEST_ENTER("q", uint64_t, 2);
     2012    TEST_ENTER("q", uint64_t, 31);
     2013#else
     2014    TEST_ENTER("l", uint32_t, 0);
     2015    TEST_ENTER("l", uint32_t, 1);
     2016    TEST_ENTER("l", uint32_t, 2);
     2017    TEST_ENTER("l", uint32_t, 31);
     2018#endif
     2019
     2020    TEST_ENTER("w", uint16_t, 0);
     2021    TEST_ENTER("w", uint16_t, 1);
     2022    TEST_ENTER("w", uint16_t, 2);
     2023    TEST_ENTER("w", uint16_t, 31);
     2024}
     2025
     2026#ifdef TEST_SSE
     2027
     2028typedef int __m64 __attribute__ ((__mode__ (__V2SI__)));
     2029typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
     2030
     2031typedef union {
     2032    double d[2];
     2033    float s[4];
     2034    uint32_t l[4];
     2035    uint64_t q[2];
     2036    __m128 dq;
     2037} XMMReg;
     2038
     2039static uint64_t __attribute__((aligned(16))) test_values[4][2] = {
     2040    { 0x456723c698694873, 0xdc515cff944a58ec },
     2041    { 0x1f297ccd58bad7ab, 0x41f21efba9e3e146 },
     2042    { 0x007c62c2085427f8, 0x231be9e8cde7438d },
     2043    { 0x0f76255a085427f8, 0xc233e9e8c4c9439a },
     2044};
     2045
     2046#define SSE_OP(op)\
     2047{\
     2048    asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
     2049    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
     2050           #op,\
     2051           a.q[1], a.q[0],\
     2052           b.q[1], b.q[0],\
     2053           r.q[1], r.q[0]);\
     2054}
     2055
     2056#define SSE_OP2(op)\
     2057{\
     2058    int i;\
     2059    for(i=0;i<2;i++) {\
     2060    a.q[0] = test_values[2*i][0];\
     2061    a.q[1] = test_values[2*i][1];\
     2062    b.q[0] = test_values[2*i+1][0];\
     2063    b.q[1] = test_values[2*i+1][1];\
     2064    SSE_OP(op);\
     2065    }\
     2066}
     2067
     2068#define MMX_OP2(op)\
     2069{\
     2070    int i;\
     2071    for(i=0;i<2;i++) {\
     2072    a.q[0] = test_values[2*i][0];\
     2073    b.q[0] = test_values[2*i+1][0];\
     2074    asm volatile (#op " %2, %0" : "=y" (r.q[0]) : "0" (a.q[0]), "y" (b.q[0]));\
     2075    printf("%-9s: a=" FMT64X " b=" FMT64X " r=" FMT64X "\n",\
     2076           #op,\
     2077           a.q[0],\
     2078           b.q[0],\
     2079           r.q[0]);\
     2080    }\
     2081    SSE_OP2(op);\
     2082}
     2083
     2084#define SHUF_OP(op, ib)\
     2085{\
     2086    a.q[0] = test_values[0][0];\
     2087    a.q[1] = test_values[0][1];\
     2088    b.q[0] = test_values[1][0];\
     2089    b.q[1] = test_values[1][1];\
     2090    asm volatile (#op " $" #ib ", %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
     2091    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
     2092           #op,\
     2093           a.q[1], a.q[0],\
     2094           b.q[1], b.q[0],\
     2095           ib,\
     2096           r.q[1], r.q[0]);\
     2097}
     2098
     2099#define PSHUF_OP(op, ib)\
     2100{\
     2101    int i;\
     2102    for(i=0;i<2;i++) {\
     2103    a.q[0] = test_values[2*i][0];\
     2104    a.q[1] = test_values[2*i][1];\
     2105    asm volatile (#op " $" #ib ", %1, %0" : "=x" (r.dq) : "x" (a.dq));\
     2106    printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
     2107           #op,\
     2108           a.q[1], a.q[0],\
     2109           ib,\
     2110           r.q[1], r.q[0]);\
     2111    }\
     2112}
     2113
     2114#define SHIFT_IM(op, ib)\
     2115{\
     2116    int i;\
     2117    for(i=0;i<2;i++) {\
     2118    a.q[0] = test_values[2*i][0];\
     2119    a.q[1] = test_values[2*i][1];\
     2120    asm volatile (#op " $" #ib ", %0" : "=x" (r.dq) : "0" (a.dq));\
     2121    printf("%-9s: a=" FMT64X "" FMT64X " ib=%02x r=" FMT64X "" FMT64X "\n",\
     2122           #op,\
     2123           a.q[1], a.q[0],\
     2124           ib,\
     2125           r.q[1], r.q[0]);\
     2126    }\
     2127}
     2128
     2129#define SHIFT_OP(op, ib)\
     2130{\
     2131    int i;\
     2132    SHIFT_IM(op, ib);\
     2133    for(i=0;i<2;i++) {\
     2134    a.q[0] = test_values[2*i][0];\
     2135    a.q[1] = test_values[2*i][1];\
     2136    b.q[0] = ib;\
     2137    b.q[1] = 0;\
     2138    asm volatile (#op " %2, %0" : "=x" (r.dq) : "0" (a.dq), "x" (b.dq));\
     2139    printf("%-9s: a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
     2140           #op,\
     2141           a.q[1], a.q[0],\
     2142           b.q[1], b.q[0],\
     2143           r.q[1], r.q[0]);\
     2144    }\
     2145}
     2146
     2147#define MOVMSK(op)\
     2148{\
     2149    int i, reg;\
     2150    for(i=0;i<2;i++) {\
     2151    a.q[0] = test_values[2*i][0];\
     2152    a.q[1] = test_values[2*i][1];\
     2153    asm volatile (#op " %1, %0" : "=r" (reg) : "x" (a.dq));\
     2154    printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\
     2155           #op,\
     2156           a.q[1], a.q[0],\
     2157           reg);\
     2158    }\
     2159}
     2160
     2161#define SSE_OPS(a) \
     2162SSE_OP(a ## ps);\
     2163SSE_OP(a ## ss);
     2164
     2165#define SSE_OPD(a) \
     2166SSE_OP(a ## pd);\
     2167SSE_OP(a ## sd);
     2168
     2169#define SSE_COMI(op, field)\
     2170{\
     2171    unsigned int eflags;\
     2172    XMMReg a, b;\
     2173    a.field[0] = a1;\
     2174    b.field[0] = b1;\
     2175    asm volatile (#op " %2, %1\n"\
     2176        "pushf\n"\
     2177        "pop %0\n"\
     2178        : "=m" (eflags)\
     2179        : "x" (a.dq), "x" (b.dq));\
     2180    printf("%-9s: a=%f b=%f cc=%04x\n",\
     2181           #op, a1, b1,\
     2182           eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
     2183}
     2184
     2185void test_sse_comi(double a1, double b1)
     2186{
     2187    SSE_COMI(ucomiss, s);
     2188    SSE_COMI(ucomisd, d);
     2189    SSE_COMI(comiss, s);
     2190    SSE_COMI(comisd, d);
     2191}
     2192
     2193#define CVT_OP_XMM(op)\
     2194{\
     2195    asm volatile (#op " %1, %0" : "=x" (r.dq) : "x" (a.dq));\
     2196    printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "" FMT64X "\n",\
     2197           #op,\
     2198           a.q[1], a.q[0],\
     2199           r.q[1], r.q[0]);\
     2200}
     2201
     2202/* Force %xmm0 usage to avoid the case where both register index are 0
     2203   to test intruction decoding more extensively */
     2204#define CVT_OP_XMM2MMX(op)\
     2205{\
     2206    asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \
     2207                  : "%xmm0");\
     2208    printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\
     2209           #op,\
     2210           a.q[1], a.q[0],\
     2211           r.q[0]);\
     2212}
     2213
     2214#define CVT_OP_MMX2XMM(op)\
     2215{\
     2216    asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\
     2217    printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\
     2218           #op,\
     2219           a.q[0],\
     2220           r.q[1], r.q[0]);\
     2221}
     2222
     2223#define CVT_OP_REG2XMM(op)\
     2224{\
     2225    asm volatile (#op " %1, %0" : "=x" (r.dq) : "r" (a.l[0]));\
     2226    printf("%-9s: a=%08x r=" FMT64X "" FMT64X "\n",\
     2227           #op,\
     2228           a.l[0],\
     2229           r.q[1], r.q[0]);\
     2230}
     2231
     2232#define CVT_OP_XMM2REG(op)\
     2233{\
     2234    asm volatile (#op " %1, %0" : "=r" (r.l[0]) : "x" (a.dq));\
     2235    printf("%-9s: a=" FMT64X "" FMT64X " r=%08x\n",\
     2236           #op,\
     2237           a.q[1], a.q[0],\
     2238           r.l[0]);\
     2239}
     2240
     2241struct fpxstate {
     2242    uint16_t fpuc;
     2243    uint16_t fpus;
     2244    uint16_t fptag;
     2245    uint16_t fop;
     2246    uint32_t fpuip;
     2247    uint16_t cs_sel;
     2248    uint16_t dummy0;
     2249    uint32_t fpudp;
     2250    uint16_t ds_sel;
     2251    uint16_t dummy1;
     2252    uint32_t mxcsr;
     2253    uint32_t mxcsr_mask;
     2254    uint8_t fpregs1[8 * 16];
     2255    uint8_t xmm_regs[8 * 16];
     2256    uint8_t dummy2[224];
     2257};
     2258
     2259static struct fpxstate fpx_state __attribute__((aligned(16)));
     2260static struct fpxstate fpx_state2 __attribute__((aligned(16)));
     2261
     2262void test_fxsave(void)
     2263{
     2264    struct fpxstate *fp = &fpx_state;
     2265    struct fpxstate *fp2 = &fpx_state2;
     2266    int i, nb_xmm;
     2267    XMMReg a, b;
     2268    a.q[0] = test_values[0][0];
     2269    a.q[1] = test_values[0][1];
     2270    b.q[0] = test_values[1][0];
     2271    b.q[1] = test_values[1][1];
     2272
     2273    asm("movdqa %2, %%xmm0\n"
     2274        "movdqa %3, %%xmm7\n"
     2275#if defined(__x86_64__)
     2276        "movdqa %2, %%xmm15\n"
     2277#endif
     2278        " fld1\n"
     2279        " fldpi\n"
     2280        " fldln2\n"
     2281        " fxsave %0\n"
     2282        " fxrstor %0\n"
     2283        " fxsave %1\n"
     2284        " fninit\n"
     2285        : "=m" (*(uint32_t *)fp2), "=m" (*(uint32_t *)fp)
     2286        : "m" (a), "m" (b));
     2287    printf("fpuc=%04x\n", fp->fpuc);
     2288    printf("fpus=%04x\n", fp->fpus);
     2289    printf("fptag=%04x\n", fp->fptag);
     2290    for(i = 0; i < 3; i++) {
     2291        printf("ST%d: " FMT64X " %04x\n",
     2292               i,
     2293               *(uint64_t *)&fp->fpregs1[i * 16],
     2294               *(uint16_t *)&fp->fpregs1[i * 16 + 8]);
     2295    }
     2296    printf("mxcsr=%08x\n", fp->mxcsr & 0x1f80);
     2297#if defined(__x86_64__)
     2298    nb_xmm = 16;
     2299#else
     2300    nb_xmm = 8;
     2301#endif
     2302    for(i = 0; i < nb_xmm; i++) {
     2303        printf("xmm%d: " FMT64X "" FMT64X "\n",
     2304               i,
     2305               *(uint64_t *)&fp->xmm_regs[i * 16],
     2306               *(uint64_t *)&fp->xmm_regs[i * 16 + 8]);
     2307    }
     2308}
     2309
     2310void test_sse(void)
     2311{
     2312    XMMReg r, a, b;
     2313    int i;
     2314
     2315    MMX_OP2(punpcklbw);
     2316    MMX_OP2(punpcklwd);
     2317    MMX_OP2(punpckldq);
     2318    MMX_OP2(packsswb);
     2319    MMX_OP2(pcmpgtb);
     2320    MMX_OP2(pcmpgtw);
     2321    MMX_OP2(pcmpgtd);
     2322    MMX_OP2(packuswb);
     2323    MMX_OP2(punpckhbw);
     2324    MMX_OP2(punpckhwd);
     2325    MMX_OP2(punpckhdq);
     2326    MMX_OP2(packssdw);
     2327    MMX_OP2(pcmpeqb);
     2328    MMX_OP2(pcmpeqw);
     2329    MMX_OP2(pcmpeqd);
     2330
     2331    MMX_OP2(paddq);
     2332    MMX_OP2(pmullw);
     2333    MMX_OP2(psubusb);
     2334    MMX_OP2(psubusw);
     2335    MMX_OP2(pminub);
     2336    MMX_OP2(pand);
     2337    MMX_OP2(paddusb);
     2338    MMX_OP2(paddusw);
     2339    MMX_OP2(pmaxub);
     2340    MMX_OP2(pandn);
     2341
     2342    MMX_OP2(pmulhuw);
     2343    MMX_OP2(pmulhw);
    16282344   
    1629 static void *call_end __init_call = NULL;
     2345    MMX_OP2(psubsb);
     2346    MMX_OP2(psubsw);
     2347    MMX_OP2(pminsw);
     2348    MMX_OP2(por);
     2349    MMX_OP2(paddsb);
     2350    MMX_OP2(paddsw);
     2351    MMX_OP2(pmaxsw);
     2352    MMX_OP2(pxor);
     2353    MMX_OP2(pmuludq);
     2354    MMX_OP2(pmaddwd);
     2355    MMX_OP2(psadbw);
     2356    MMX_OP2(psubb);
     2357    MMX_OP2(psubw);
     2358    MMX_OP2(psubd);
     2359    MMX_OP2(psubq);
     2360    MMX_OP2(paddb);
     2361    MMX_OP2(paddw);
     2362    MMX_OP2(paddd);
     2363
     2364    MMX_OP2(pavgb);
     2365    MMX_OP2(pavgw);
     2366
     2367    asm volatile ("pinsrw $1, %1, %0" : "=y" (r.q[0]) : "r" (0x12345678));
     2368    printf("%-9s: r=" FMT64X "\n", "pinsrw", r.q[0]);
     2369
     2370    asm volatile ("pinsrw $5, %1, %0" : "=x" (r.dq) : "r" (0x12345678));
     2371    printf("%-9s: r=" FMT64X "" FMT64X "\n", "pinsrw", r.q[1], r.q[0]);
     2372
     2373    a.q[0] = test_values[0][0];
     2374    a.q[1] = test_values[0][1];
     2375    asm volatile ("pextrw $1, %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
     2376    printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
     2377
     2378    asm volatile ("pextrw $5, %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
     2379    printf("%-9s: r=%08x\n", "pextrw", r.l[0]);
     2380
     2381    asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "y" (a.q[0]));
     2382    printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
     2383   
     2384    asm volatile ("pmovmskb %1, %0" : "=r" (r.l[0]) : "x" (a.dq));
     2385    printf("%-9s: r=%08x\n", "pmovmskb", r.l[0]);
     2386
     2387    {
     2388        r.q[0] = -1;
     2389        r.q[1] = -1;
     2390
     2391        a.q[0] = test_values[0][0];
     2392        a.q[1] = test_values[0][1];
     2393        b.q[0] = test_values[1][0];
     2394        b.q[1] = test_values[1][1];
     2395        asm volatile("maskmovq %1, %0" :
     2396                     : "y" (a.q[0]), "y" (b.q[0]), "D" (&r)
     2397                     : "memory");
     2398        printf("%-9s: r=" FMT64X " a=" FMT64X " b=" FMT64X "\n",
     2399               "maskmov",
     2400               r.q[0],
     2401               a.q[0],
     2402               b.q[0]);
     2403        asm volatile("maskmovdqu %1, %0" :
     2404                     : "x" (a.dq), "x" (b.dq), "D" (&r)
     2405                     : "memory");
     2406        printf("%-9s: r=" FMT64X "" FMT64X " a=" FMT64X "" FMT64X " b=" FMT64X "" FMT64X "\n",
     2407               "maskmov",
     2408               r.q[1], r.q[0],
     2409               a.q[1], a.q[0],
     2410               b.q[1], b.q[0]);
     2411    }
     2412
     2413    asm volatile ("emms");
     2414
     2415    SSE_OP2(punpcklqdq);
     2416    SSE_OP2(punpckhqdq);
     2417    SSE_OP2(andps);
     2418    SSE_OP2(andpd);
     2419    SSE_OP2(andnps);
     2420    SSE_OP2(andnpd);
     2421    SSE_OP2(orps);
     2422    SSE_OP2(orpd);
     2423    SSE_OP2(xorps);
     2424    SSE_OP2(xorpd);
     2425
     2426    SSE_OP2(unpcklps);
     2427    SSE_OP2(unpcklpd);
     2428    SSE_OP2(unpckhps);
     2429    SSE_OP2(unpckhpd);
     2430
     2431    SHUF_OP(shufps, 0x78);
     2432    SHUF_OP(shufpd, 0x02);
     2433
     2434    PSHUF_OP(pshufd, 0x78);
     2435    PSHUF_OP(pshuflw, 0x78);
     2436    PSHUF_OP(pshufhw, 0x78);
     2437
     2438    SHIFT_OP(psrlw, 7);
     2439    SHIFT_OP(psrlw, 16);
     2440    SHIFT_OP(psraw, 7);
     2441    SHIFT_OP(psraw, 16);
     2442    SHIFT_OP(psllw, 7);
     2443    SHIFT_OP(psllw, 16);
     2444
     2445    SHIFT_OP(psrld, 7);
     2446    SHIFT_OP(psrld, 32);
     2447    SHIFT_OP(psrad, 7);
     2448    SHIFT_OP(psrad, 32);
     2449    SHIFT_OP(pslld, 7);
     2450    SHIFT_OP(pslld, 32);
     2451
     2452    SHIFT_OP(psrlq, 7);
     2453    SHIFT_OP(psrlq, 32);
     2454    SHIFT_OP(psllq, 7);
     2455    SHIFT_OP(psllq, 32);
     2456
     2457    SHIFT_IM(psrldq, 16);
     2458    SHIFT_IM(psrldq, 7);
     2459    SHIFT_IM(pslldq, 16);
     2460    SHIFT_IM(pslldq, 7);
     2461
     2462    MOVMSK(movmskps);
     2463    MOVMSK(movmskpd);
     2464
     2465    /* FPU specific ops */
     2466
     2467    {
     2468        uint32_t mxcsr;
     2469        asm volatile("stmxcsr %0" : "=m" (mxcsr));
     2470        printf("mxcsr=%08x\n", mxcsr & 0x1f80);
     2471        asm volatile("ldmxcsr %0" : : "m" (mxcsr));
     2472    }
     2473
     2474    test_sse_comi(2, -1);
     2475    test_sse_comi(2, 2);
     2476    test_sse_comi(2, 3);
     2477    test_sse_comi(2, q_nan.d);
     2478    test_sse_comi(q_nan.d, -1);
     2479
     2480    for(i = 0; i < 2; i++) {
     2481        a.s[0] = 2.7;
     2482        a.s[1] = 3.4;
     2483        a.s[2] = 4;
     2484        a.s[3] = -6.3;
     2485        b.s[0] = 45.7;
     2486        b.s[1] = 353.4;
     2487        b.s[2] = 4;
     2488        b.s[3] = 56.3;
     2489        if (i == 1) {
     2490            a.s[0] = q_nan.d;
     2491            b.s[3] = q_nan.d;
     2492        }
     2493
     2494        SSE_OPS(add);
     2495        SSE_OPS(mul);
     2496        SSE_OPS(sub);
     2497        SSE_OPS(min);
     2498        SSE_OPS(div);
     2499        SSE_OPS(max);
     2500        SSE_OPS(sqrt);
     2501        SSE_OPS(cmpeq);
     2502        SSE_OPS(cmplt);
     2503        SSE_OPS(cmple);
     2504        SSE_OPS(cmpunord);
     2505        SSE_OPS(cmpneq);
     2506        SSE_OPS(cmpnlt);
     2507        SSE_OPS(cmpnle);
     2508        SSE_OPS(cmpord);
     2509       
     2510       
     2511        a.d[0] = 2.7;
     2512        a.d[1] = -3.4;
     2513        b.d[0] = 45.7;
     2514        b.d[1] = -53.4;
     2515        if (i == 1) {
     2516            a.d[0] = q_nan.d;
     2517            b.d[1] = q_nan.d;
     2518        }
     2519        SSE_OPD(add);
     2520        SSE_OPD(mul);
     2521        SSE_OPD(sub);
     2522        SSE_OPD(min);
     2523        SSE_OPD(div);
     2524        SSE_OPD(max);
     2525        SSE_OPD(sqrt);
     2526        SSE_OPD(cmpeq);
     2527        SSE_OPD(cmplt);
     2528        SSE_OPD(cmple);
     2529        SSE_OPD(cmpunord);
     2530        SSE_OPD(cmpneq);
     2531        SSE_OPD(cmpnlt);
     2532        SSE_OPD(cmpnle);
     2533        SSE_OPD(cmpord);
     2534    }
     2535
     2536    /* float to float/int */
     2537    a.s[0] = 2.7;
     2538    a.s[1] = 3.4;
     2539    a.s[2] = 4;
     2540    a.s[3] = -6.3;
     2541    CVT_OP_XMM(cvtps2pd);
     2542    CVT_OP_XMM(cvtss2sd);
     2543    CVT_OP_XMM2MMX(cvtps2pi);
     2544    CVT_OP_XMM2MMX(cvttps2pi);
     2545    CVT_OP_XMM2REG(cvtss2si);
     2546    CVT_OP_XMM2REG(cvttss2si);
     2547    CVT_OP_XMM(cvtps2dq);
     2548    CVT_OP_XMM(cvttps2dq);
     2549
     2550    a.d[0] = 2.6;
     2551    a.d[1] = -3.4;
     2552    CVT_OP_XMM(cvtpd2ps);
     2553    CVT_OP_XMM(cvtsd2ss);
     2554    CVT_OP_XMM2MMX(cvtpd2pi);
     2555    CVT_OP_XMM2MMX(cvttpd2pi);
     2556    CVT_OP_XMM2REG(cvtsd2si);
     2557    CVT_OP_XMM2REG(cvttsd2si);
     2558    CVT_OP_XMM(cvtpd2dq);
     2559    CVT_OP_XMM(cvttpd2dq);
     2560
     2561    /* sse/mmx moves */
     2562    CVT_OP_XMM2MMX(movdq2q);
     2563    CVT_OP_MMX2XMM(movq2dq);
     2564
     2565    /* int to float */
     2566    a.l[0] = -6;
     2567    a.l[1] = 2;
     2568    a.l[2] = 100;
     2569    a.l[3] = -60000;
     2570    CVT_OP_MMX2XMM(cvtpi2ps);
     2571    CVT_OP_MMX2XMM(cvtpi2pd);
     2572    CVT_OP_REG2XMM(cvtsi2ss);
     2573    CVT_OP_REG2XMM(cvtsi2sd);
     2574    CVT_OP_XMM(cvtdq2ps);
     2575    CVT_OP_XMM(cvtdq2pd);
     2576
     2577    /* XXX: test PNI insns */
     2578#if 0
     2579    SSE_OP2(movshdup);
     2580#endif
     2581    asm volatile ("emms");
     2582}
     2583
     2584#endif
     2585
     2586extern void *__start_initcall;
     2587extern void *__stop_initcall;
     2588
    16302589
    16312590int main(int argc, char **argv)
     
    16342593    void (*func)(void);
    16352594
    1636     ptr = &call_start + 1;
    1637     while (*ptr != NULL) {
     2595    ptr = &__start_initcall;
     2596    while (ptr != &__stop_initcall) {
    16382597        func = *ptr++;
    16392598        func();
     
    16432602    test_jcc();
    16442603    test_floats();
     2604#if !defined(__x86_64__)
    16452605    test_bcd();
     2606#endif
    16462607    test_xchg();
    16472608    test_string();
    16482609    test_misc();
    16492610    test_lea();
     2611#ifdef TEST_SEGS
    16502612    test_segs();
    16512613    test_code16();
     2614#endif
     2615#ifdef TEST_VM86
    16522616    test_vm86();
     2617#endif
    16532618    test_exceptions();
     2619#if !defined(__x86_64__)
    16542620    test_self_modifying_code();
    16552621    test_single_step();
     2622#endif
     2623    test_enter();
     2624#ifdef TEST_SSE
     2625    test_sse();
     2626    test_fxsave();
     2627#endif
    16562628    return 0;
    16572629}
  • trunk/src/recompiler/tests/test-i386.h

    r1 r2426  
    11
    22#define exec_op glue(exec_, OP)
     3#define exec_opq glue(glue(exec_, OP), q)
    34#define exec_opl glue(glue(exec_, OP), l)
    45#define exec_opw glue(glue(exec_, OP), w)
    56#define exec_opb glue(glue(exec_, OP), b)
    67
    7 #define EXECOP2(size, res, s1, flags) \
     8#define EXECOP2(size, rsize, res, s1, flags) \
    89    asm ("push %4\n\t"\
    910         "popf\n\t"\
    10          stringify(OP) size " %" size "2, %" size "0\n\t" \
     11         stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \
    1112         "pushf\n\t"\
    12          "popl %1\n\t"\
     13         "pop %1\n\t"\
    1314         : "=q" (res), "=g" (flags)\
    14          : "q" (s1), "0" (res), "1" (flags));
     15         : "q" (s1), "0" (res), "1" (flags)); \
     16    printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", \
     17           stringify(OP) size, s0, s1, res, iflags, flags & CC_MASK);
    1518
    16 #define EXECOP1(size, res, flags) \
     19#define EXECOP1(size, rsize, res, flags) \
    1720    asm ("push %3\n\t"\
    1821         "popf\n\t"\
    19          stringify(OP) size " %" size "0\n\t" \
     22         stringify(OP) size " %" rsize "0\n\t" \
    2023         "pushf\n\t"\
    21          "popl %1\n\t"\
     24         "pop %1\n\t"\
    2225         : "=q" (res), "=g" (flags)\
    23          : "0" (res), "1" (flags));
     26         : "0" (res), "1" (flags)); \
     27    printf("%-10s A=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", \
     28           stringify(OP) size, s0, res, iflags, flags & CC_MASK);
    2429
    2530#ifdef OP1
    26 void exec_opl(int s0, int s1, int iflags)
     31#if defined(__x86_64__)
     32void exec_opq(long s0, long s1, long iflags)
    2733{
    28     int res, flags;
     34    long res, flags;
    2935    res = s0;
    3036    flags = iflags;
    31     EXECOP1("", res, flags);
    32     printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",
    33            stringify(OP) "l", s0, res, iflags, flags & CC_MASK);
    34 }
    35 
    36 void exec_opw(int s0, int s1, int iflags)
    37 {
    38     int res, flags;
    39     res = s0;
    40     flags = iflags;
    41     EXECOP1("w", res, flags);
    42     printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",
    43            stringify(OP) "w", s0, res, iflags, flags & CC_MASK);
    44 }
    45 
    46 void exec_opb(int s0, int s1, int iflags)
    47 {
    48     int res, flags;
    49     res = s0;
    50     flags = iflags;
    51     EXECOP1("b", res, flags);
    52     printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",
    53            stringify(OP) "b", s0, res, iflags, flags & CC_MASK);
    54 }
    55 #else
    56 void exec_opl(int s0, int s1, int iflags)
    57 {
    58     int res, flags;
    59     res = s0;
    60     flags = iflags;
    61     EXECOP2("", res, s1, flags);
    62     printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
    63            stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
    64 }
    65 
    66 void exec_opw(int s0, int s1, int iflags)
    67 {
    68     int res, flags;
    69     res = s0;
    70     flags = iflags;
    71     EXECOP2("w", res, s1, flags);
    72     printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
    73            stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
    74 }
    75 
    76 void exec_opb(int s0, int s1, int iflags)
    77 {
    78     int res, flags;
    79     res = s0;
    80     flags = iflags;
    81     EXECOP2("b", res, s1, flags);
    82     printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
    83            stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
     37    EXECOP1("q", "", res, flags);
    8438}
    8539#endif
    8640
    87 void exec_op(int s0, int s1)
     41void exec_opl(long s0, long s1, long iflags)
    8842{
     43    long res, flags;
     44    res = s0;
     45    flags = iflags;
     46    EXECOP1("l", "k", res, flags);
     47}
     48
     49void exec_opw(long s0, long s1, long iflags)
     50{
     51    long res, flags;
     52    res = s0;
     53    flags = iflags;
     54    EXECOP1("w", "w", res, flags);
     55}
     56
     57void exec_opb(long s0, long s1, long iflags)
     58{
     59    long res, flags;
     60    res = s0;
     61    flags = iflags;
     62    EXECOP1("b", "b", res, flags);
     63}
     64#else
     65#if defined(__x86_64__)
     66void exec_opq(long s0, long s1, long iflags)
     67{
     68    long res, flags;
     69    res = s0;
     70    flags = iflags;
     71    EXECOP2("q", "", res, s1, flags);
     72}
     73#endif
     74
     75void exec_opl(long s0, long s1, long iflags)
     76{
     77    long res, flags;
     78    res = s0;
     79    flags = iflags;
     80    EXECOP2("l", "k", res, s1, flags);
     81}
     82
     83void exec_opw(long s0, long s1, long iflags)
     84{
     85    long res, flags;
     86    res = s0;
     87    flags = iflags;
     88    EXECOP2("w", "w", res, s1, flags);
     89}
     90
     91void exec_opb(long s0, long s1, long iflags)
     92{
     93    long res, flags;
     94    res = s0;
     95    flags = iflags;
     96    EXECOP2("b", "b", res, s1, flags);
     97}
     98#endif
     99
     100void exec_op(long s0, long s1)
     101{
     102    s0 = i2l(s0);
     103    s1 = i2l(s1);
     104#if defined(__x86_64__)
     105    exec_opq(s0, s1, 0);
     106#endif
    89107    exec_opl(s0, s1, 0);
    90108    exec_opw(s0, s1, 0);
    91109    exec_opb(s0, s1, 0);
    92110#ifdef OP_CC
     111#if defined(__x86_64__)
     112    exec_opq(s0, s1, CC_C);
     113#endif
    93114    exec_opl(s0, s1, CC_C);
    94115    exec_opw(s0, s1, CC_C);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette