Revision 4b74fe1f op-i386.c

b/op-i386.c
10 10
typedef signed int int32_t;
11 11
typedef signed long long int64_t;
12 12

  
13
#define bswap32(x) \
14
({ \
15
	uint32_t __x = (x); \
16
	((uint32_t)( \
17
		(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
18
		(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
19
		(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
20
		(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
21
})
22

  
13 23
#define NULL 0
24
#include <fenv.h>
14 25

  
15 26
typedef struct FILE FILE;
16 27
extern FILE *logfile;
......
18 29
extern int fprintf(FILE *, const char *, ...);
19 30

  
20 31
#ifdef __i386__
21
register int T0 asm("esi");
22
register int T1 asm("ebx");
23
register int A0 asm("edi");
32
register unsigned int T0 asm("ebx");
33
register unsigned int T1 asm("esi");
34
register unsigned int A0 asm("edi");
24 35
register struct CPUX86State *env asm("ebp");
25
#define FORCE_RET() asm volatile ("ret");
26 36
#endif
27 37
#ifdef __powerpc__
28
register int T0 asm("r24");
29
register int T1 asm("r25");
30
register int A0 asm("r26");
38
register unsigned int T0 asm("r24");
39
register unsigned int T1 asm("r25");
40
register unsigned int A0 asm("r26");
31 41
register struct CPUX86State *env asm("r27");
32
#define FORCE_RET() asm volatile ("blr");
33 42
#endif
34 43
#ifdef __arm__
35
register int T0 asm("r4");
36
register int T1 asm("r5");
37
register int A0 asm("r6");
44
register unsigned int T0 asm("r4");
45
register unsigned int T1 asm("r5");
46
register unsigned int A0 asm("r6");
38 47
register struct CPUX86State *env asm("r7");
39
#define FORCE_RET() asm volatile ("mov pc, lr");
40 48
#endif
41 49
#ifdef __mips__
42
register int T0 asm("s0");
43
register int T1 asm("s1");
44
register int A0 asm("s2");
50
register unsigned int T0 asm("s0");
51
register unsigned int T1 asm("s1");
52
register unsigned int A0 asm("s2");
45 53
register struct CPUX86State *env asm("s3");
46
#define FORCE_RET() asm volatile ("jr $31");
47 54
#endif
48 55
#ifdef __sparc__
49
register int T0 asm("l0");
50
register int T1 asm("l1");
51
register int A0 asm("l2");
56
register unsigned int T0 asm("l0");
57
register unsigned int T1 asm("l1");
58
register unsigned int A0 asm("l2");
52 59
register struct CPUX86State *env asm("l3");
53
#define FORCE_RET() asm volatile ("retl ; nop");
54 60
#endif
55 61

  
62
/* force GCC to generate only one epilog at the end of the function */
63
#define FORCE_RET() asm volatile ("");
64

  
56 65
#ifndef OPPROTO
57 66
#define OPPROTO
58 67
#endif
......
267 276
    CC_DST = T0;
268 277
}
269 278

  
270
void OPPROTO op_adcl_T0_T1_cc(void)
271
{
272
    CC_SRC = T0;
273
    T0 = T0 + T1 + cc_table[CC_OP].compute_c();
274
    CC_DST = T0;
275
}
276

  
277
void OPPROTO op_sbbl_T0_T1_cc(void)
278
{
279
    CC_SRC = T0;
280
    T0 = T0 - T1 - cc_table[CC_OP].compute_c();
281
    CC_DST = T0;
282
}
283

  
284 279
void OPPROTO op_andl_T0_T1_cc(void)
285 280
{
286 281
    T0 &= T1;
......
320 315

  
321 316
void OPPROTO op_incl_T0_cc(void)
322 317
{
318
    CC_SRC = cc_table[CC_OP].compute_c();
323 319
    T0++;
324 320
    CC_DST = T0;
325 321
}
326 322

  
327 323
void OPPROTO op_decl_T0_cc(void)
328 324
{
325
    CC_SRC = cc_table[CC_OP].compute_c();
329 326
    T0--;
330 327
    CC_DST = T0;
331 328
}
......
335 332
    CC_DST = T0 & T1;
336 333
}
337 334

  
335
void OPPROTO op_bswapl_T0(void)
336
{
337
    T0 = bswap32(T0);
338
}
339

  
338 340
/* multiply/divide */
339 341
void OPPROTO op_mulb_AL_T0(void)
340 342
{
......
399 401
void OPPROTO op_imull_T0_T1(void)
400 402
{
401 403
    int64_t res;
402
    res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T1);
404
    res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
403 405
    T0 = res;
404 406
    CC_SRC = (res != (int32_t)res);
405 407
}
......
468 470
void OPPROTO op_idivl_EAX_T0(void)
469 471
{
470 472
    int den, q, r;
471
    int16_t num;
473
    int64_t num;
472 474
    
473 475
    num = EAX | ((uint64_t)EDX << 32);
474
    den = (int16_t)T0;
476
    den = T0;
475 477
    q = (num / den);
476 478
    r = (num % den);
477 479
    EAX = q;
......
495 497
    A0 = PARAM1;
496 498
}
497 499

  
500
void OPPROTO op_addl_A0_im(void)
501
{
502
    A0 += PARAM1;
503
}
504

  
505
void OPPROTO op_andl_A0_ffff(void)
506
{
507
    A0 = A0 & 0xffff;
508
}
509

  
498 510
/* memory access */
499 511

  
500 512
void OPPROTO op_ldub_T0_A0(void)
......
562 574
    stl((uint8_t *)A0, T0);
563 575
}
564 576

  
565
/* jumps */
577
/* used for bit operations */
578

  
579
void OPPROTO op_add_bitw_A0_T1(void)
580
{
581
    A0 += ((int32_t)T1 >> 4) << 1;
582
}
583

  
584
void OPPROTO op_add_bitl_A0_T1(void)
585
{
586
    A0 += ((int32_t)T1 >> 5) << 2;
587
}
566 588

  
567 589
/* indirect jump */
568 590

  
......
938 960
    [CC_OP_ADDW] = { compute_all_addw, compute_c_addw  },
939 961
    [CC_OP_ADDL] = { compute_all_addl, compute_c_addl  },
940 962

  
963
    [CC_OP_ADCB] = { compute_all_adcb, compute_c_adcb },
964
    [CC_OP_ADCW] = { compute_all_adcw, compute_c_adcw  },
965
    [CC_OP_ADCL] = { compute_all_adcl, compute_c_adcl  },
966

  
941 967
    [CC_OP_SUBB] = { compute_all_subb, compute_c_subb  },
942 968
    [CC_OP_SUBW] = { compute_all_subw, compute_c_subw  },
943 969
    [CC_OP_SUBL] = { compute_all_subl, compute_c_subl  },
944 970
    
971
    [CC_OP_SBBB] = { compute_all_sbbb, compute_c_sbbb  },
972
    [CC_OP_SBBW] = { compute_all_sbbw, compute_c_sbbw  },
973
    [CC_OP_SBBL] = { compute_all_sbbl, compute_c_sbbl  },
974
    
945 975
    [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb },
946 976
    [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw },
947 977
    [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl },
948 978
    
949
    [CC_OP_INCB] = { compute_all_incb, compute_c_incb },
950
    [CC_OP_INCW] = { compute_all_incw, compute_c_incw },
979
    [CC_OP_INCB] = { compute_all_incb, compute_c_incl },
980
    [CC_OP_INCW] = { compute_all_incw, compute_c_incl },
951 981
    [CC_OP_INCL] = { compute_all_incl, compute_c_incl },
952 982
    
953
    [CC_OP_DECB] = { compute_all_decb, compute_c_incb },
954
    [CC_OP_DECW] = { compute_all_decw, compute_c_incw },
983
    [CC_OP_DECB] = { compute_all_decb, compute_c_incl },
984
    [CC_OP_DECW] = { compute_all_decw, compute_c_incl },
955 985
    [CC_OP_DECL] = { compute_all_decl, compute_c_incl },
956 986
    
957
    [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb },
958
    [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw },
987
    [CC_OP_SHLB] = { compute_all_shlb, compute_c_shll },
988
    [CC_OP_SHLW] = { compute_all_shlw, compute_c_shll },
959 989
    [CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
990

  
991
    [CC_OP_SARB] = { compute_all_sarb, compute_c_shll },
992
    [CC_OP_SARW] = { compute_all_sarw, compute_c_shll },
993
    [CC_OP_SARL] = { compute_all_sarl, compute_c_shll },
960 994
};
961 995

  
962 996
/* floating point support */
......
1640 1674
    helper_fcos();
1641 1675
}
1642 1676

  
1677
void OPPROTO op_fnstsw_A0(void)
1678
{
1679
    int fpus;
1680
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1681
    stw((void *)A0, fpus);
1682
}
1683

  
1684
void OPPROTO op_fnstcw_A0(void)
1685
{
1686
    stw((void *)A0, env->fpuc);
1687
}
1688

  
1689
void OPPROTO op_fldcw_A0(void)
1690
{
1691
    int rnd_type;
1692
    env->fpuc = lduw((void *)A0);
1693
    /* set rounding mode */
1694
    switch(env->fpuc & RC_MASK) {
1695
    default:
1696
    case RC_NEAR:
1697
        rnd_type = FE_TONEAREST;
1698
        break;
1699
    case RC_DOWN:
1700
        rnd_type = FE_DOWNWARD;
1701
        break;
1702
    case RC_UP:
1703
        rnd_type = FE_UPWARD;
1704
        break;
1705
    case RC_CHOP:
1706
        rnd_type = FE_TOWARDZERO;
1707
        break;
1708
    }
1709
    fesetround(rnd_type);
1710
}
1711

  
1643 1712
/* main execution loop */
1644 1713
uint8_t code_gen_buffer[65536];
1645 1714

  
......
1651 1720
    "ADDB",
1652 1721
    "ADDW",
1653 1722
    "ADDL",
1723
    "ADCB",
1724
    "ADCW",
1725
    "ADCL",
1654 1726
    "SUBB",
1655 1727
    "SUBW",
1656 1728
    "SUBL",
1729
    "SBBB",
1730
    "SBBW",
1731
    "SBBL",
1657 1732
    "LOGICB",
1658 1733
    "LOGICW",
1659 1734
    "LOGICL",
......
1666 1741
    "SHLB",
1667 1742
    "SHLW",
1668 1743
    "SHLL",
1744
    "SARB",
1745
    "SARW",
1746
    "SARL",
1669 1747
};
1670 1748
#endif
1671 1749

  
......
1688 1766
        for(;;) {
1689 1767
#ifdef DEBUG_EXEC
1690 1768
            if (loglevel) {
1769
                int eflags;
1770
                eflags = cc_table[CC_OP].compute_all();
1771
                eflags |= (DF & DIRECTION_FLAG);
1691 1772
                fprintf(logfile, 
1692 1773
                        "EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n"
1693
                        "ESI=%08x ESI=%08X EBP=%08x ESP=%08x\n"
1694
                        "CCS=%08x CCD=%08x CCOP=%s\n",
1774
                        "ESI=%08x EDI=%08X EBP=%08x ESP=%08x\n"
1775
                        "CCS=%08x CCD=%08x CCO=%-8s EFL=%c%c%c%c%c%c%c\n",
1695 1776
                        env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], 
1696 1777
                        env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP], 
1697
                        env->cc_src, env->cc_dst, cc_op_str[env->cc_op]);
1778
                        env->cc_src, env->cc_dst, cc_op_str[env->cc_op],
1779
                        eflags & DIRECTION_FLAG ? 'D' : '-',
1780
                        eflags & CC_O ? 'O' : '-',
1781
                        eflags & CC_S ? 'S' : '-',
1782
                        eflags & CC_Z ? 'Z' : '-',
1783
                        eflags & CC_A ? 'A' : '-',
1784
                        eflags & CC_P ? 'P' : '-',
1785
                        eflags & CC_C ? 'C' : '-'
1786
                        );
1698 1787
            }
1699 1788
#endif
1700 1789
            cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc);

Also available in: Unified diff