Revision 4b74fe1f

b/cpu-i386.h
78 78
    CC_OP_ADDW,
79 79
    CC_OP_ADDL,
80 80

  
81
    CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
82
    CC_OP_ADCW,
83
    CC_OP_ADCL,
84

  
81 85
    CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
82 86
    CC_OP_SUBW,
83 87
    CC_OP_SUBL,
84 88

  
89
    CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
90
    CC_OP_SBBW,
91
    CC_OP_SBBL,
92

  
85 93
    CC_OP_LOGICB, /* modify all flags, CC_DST = res */
86 94
    CC_OP_LOGICW,
87 95
    CC_OP_LOGICL,
88 96

  
89
    CC_OP_INCB, /* modify all flags except, CC_DST = res */
97
    CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */
90 98
    CC_OP_INCW,
91 99
    CC_OP_INCL,
92 100

  
93
    CC_OP_DECB, /* modify all flags except, CC_DST = res */
101
    CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C  */
94 102
    CC_OP_DECW,
95 103
    CC_OP_DECL,
96 104

  
......
98 106
    CC_OP_SHLW,
99 107
    CC_OP_SHLL,
100 108

  
109
    CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
110
    CC_OP_SARW,
111
    CC_OP_SARL,
112

  
101 113
    CC_OP_NB,
102 114
};
103 115

  
b/dyngen.c
198 198
        {
199 199
            uint8_t *p;
200 200
            p = p_end - 1;
201
            /* find ret */
202
            while (p > p_start && *p != 0xc3)
203
                p--;
204
            /* skip double ret */
205
            if (p > p_start && p[-1] == 0xc3)
206
                p--;
207 201
            if (p == p_start)
208 202
                error("empty code for %s", name);
203
            if (p[0] != 0xc3)
204
                error("ret expected at the end of %s", name);
209 205
            copy_size = p - p_start;
210 206
        }
211 207
        break;
b/linux-user/main.c
128 128
    /* Zero out image_info */
129 129
    memset(info, 0, sizeof(struct image_info));
130 130

  
131
    if(elf_exec(filename, argv+1, environ, regs, info) != 0) {
131
    if(elf_exec(filename, argv+optind, environ, regs, info) != 0) {
132 132
	printf("Error loading %s\n", filename);
133 133
	exit(1);
134 134
    }
135 135
    
136
#if 0
137
    printf("start_brk   0x%08lx\n" , info->start_brk);
138
    printf("end_code    0x%08lx\n" , info->end_code);
139
    printf("start_code  0x%08lx\n" , info->start_code);
140
    printf("end_data    0x%08lx\n" , info->end_data);
141
    printf("start_stack 0x%08lx\n" , info->start_stack);
142
    printf("brk         0x%08lx\n" , info->brk);
143
    printf("esp         0x%08lx\n" , regs->esp);
144
    printf("eip         0x%08lx\n" , regs->eip);
145
#endif
136
    if (loglevel) {
137
        fprintf(logfile, "start_brk   0x%08lx\n" , info->start_brk);
138
        fprintf(logfile, "end_code    0x%08lx\n" , info->end_code);
139
        fprintf(logfile, "start_code  0x%08lx\n" , info->start_code);
140
        fprintf(logfile, "end_data    0x%08lx\n" , info->end_data);
141
        fprintf(logfile, "start_stack 0x%08lx\n" , info->start_stack);
142
        fprintf(logfile, "brk         0x%08lx\n" , info->brk);
143
        fprintf(logfile, "esp         0x%08lx\n" , regs->esp);
144
        fprintf(logfile, "eip         0x%08lx\n" , regs->eip);
145
    }
146 146

  
147 147
    target_set_brk((char *)info->brk);
148 148
    syscall_init();
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);
b/ops_template.h
33 33
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
34 34
    pf = parity_table[(uint8_t)CC_DST];
35 35
    af = (CC_DST ^ src1 ^ src2) & 0x10;
36
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
36
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
37 37
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
38 38
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
39 39
    return cf | pf | af | zf | sf | of;
......
47 47
    return cf;
48 48
}
49 49

  
50
static int glue(compute_all_adc, SUFFIX)(void)
51
{
52
    int cf, pf, af, zf, sf, of;
53
    int src1, src2;
54
    src1 = CC_SRC;
55
    src2 = CC_DST - CC_SRC - 1;
56
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
57
    pf = parity_table[(uint8_t)CC_DST];
58
    af = (CC_DST ^ src1 ^ src2) & 0x10;
59
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
60
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
61
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
62
    return cf | pf | af | zf | sf | of;
63
}
64

  
65
static int glue(compute_c_adc, SUFFIX)(void)
66
{
67
    int src1, cf;
68
    src1 = CC_SRC;
69
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
70
    return cf;
71
}
72

  
50 73
static int glue(compute_all_sub, SUFFIX)(void)
51 74
{
52 75
    int cf, pf, af, zf, sf, of;
......
56 79
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
57 80
    pf = parity_table[(uint8_t)CC_DST];
58 81
    af = (CC_DST ^ src1 ^ src2) & 0x10;
59
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
82
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
60 83
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
61
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
84
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
62 85
    return cf | pf | af | zf | sf | of;
63 86
}
64 87

  
......
67 90
    int src1, src2, cf;
68 91
    src1 = CC_SRC;
69 92
    src2 = CC_SRC - CC_DST;
70
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src1;
93
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
94
    return cf;
95
}
96

  
97
static int glue(compute_all_sbb, SUFFIX)(void)
98
{
99
    int cf, pf, af, zf, sf, of;
100
    int src1, src2;
101
    src1 = CC_SRC;
102
    src2 = CC_SRC - CC_DST - 1;
103
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
104
    pf = parity_table[(uint8_t)CC_DST];
105
    af = (CC_DST ^ src1 ^ src2) & 0x10;
106
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
107
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
108
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
109
    return cf | pf | af | zf | sf | of;
110
}
111

  
112
static int glue(compute_c_sbb, SUFFIX)(void)
113
{
114
    int src1, src2, cf;
115
    src1 = CC_SRC;
116
    src2 = CC_SRC - CC_DST - 1;
117
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
71 118
    return cf;
72 119
}
73 120

  
......
77 124
    cf = 0;
78 125
    pf = parity_table[(uint8_t)CC_DST];
79 126
    af = 0;
80
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
127
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
81 128
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
82 129
    of = 0;
83 130
    return cf | pf | af | zf | sf | of;
......
97 144
    cf = CC_SRC;
98 145
    pf = parity_table[(uint8_t)CC_DST];
99 146
    af = (CC_DST ^ src1 ^ src2) & 0x10;
100
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
147
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
101 148
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
102
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
149
    of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
103 150
    return cf | pf | af | zf | sf | of;
104 151
}
105 152

  
153
#if DATA_BITS == 32
106 154
static int glue(compute_c_inc, SUFFIX)(void)
107 155
{
108 156
    return CC_SRC;
109 157
}
158
#endif
110 159

  
111 160
static int glue(compute_all_dec, SUFFIX)(void)
112 161
{
......
117 166
    cf = CC_SRC;
118 167
    pf = parity_table[(uint8_t)CC_DST];
119 168
    af = (CC_DST ^ src1 ^ src2) & 0x10;
120
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
169
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
121 170
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
122
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
171
    of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
123 172
    return cf | pf | af | zf | sf | of;
124 173
}
125 174

  
......
129 178
    cf = CC_SRC & 1;
130 179
    pf = parity_table[(uint8_t)CC_DST];
131 180
    af = 0; /* undefined */
132
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
181
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
133 182
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
134
    of = sf << 4; /* only meaniful for shr with count == 1 */
183
    of = lshift(CC_SRC, 12 - DATA_BITS) & CC_O; /* only meaniful for shr with count == 1 */
135 184
    return cf | pf | af | zf | sf | of;
136 185
}
137 186

  
187
#if DATA_BITS == 32
138 188
static int glue(compute_c_shl, SUFFIX)(void)
139 189
{
140 190
    return CC_SRC & 1;
141 191
}
192
#endif
193

  
194
static int glue(compute_all_sar, SUFFIX)(void)
195
{
196
    int cf, pf, af, zf, sf, of;
197
    cf = CC_SRC & 1;
198
    pf = parity_table[(uint8_t)CC_DST];
199
    af = 0; /* undefined */
200
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
201
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
202
    of = 0; /* only meaniful for shr with count == 1 */
203
    return cf | pf | af | zf | sf | of;
204
}
142 205

  
143 206
/* various optimized jumps cases */
144 207

  
......
157 220

  
158 221
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
159 222
{
160
    if ((DATA_TYPE)CC_DST != 0)
223
    if ((DATA_TYPE)CC_DST == 0)
161 224
        PC = PARAM1;
162 225
    else
163 226
        PC = PARAM2;
......
225 288

  
226 289
void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
227 290
{
228
    T0 = ((DATA_TYPE)CC_DST != 0);
291
    T0 = ((DATA_TYPE)CC_DST == 0);
229 292
}
230 293

  
231 294
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
......
275 338
            (T0 & CC_C);
276 339
        CC_OP = CC_OP_EFLAGS;
277 340
    }
341
    FORCE_RET();
278 342
}
279 343

  
280 344
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
......
290 354
            ((T0 >> (DATA_BITS - 1)) & CC_C);
291 355
        CC_OP = CC_OP_EFLAGS;
292 356
    }
357
    FORCE_RET();
293 358
}
294 359

  
295 360
void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
......
305 370
#endif
306 371
    if (count) {
307 372
        eflags = cc_table[CC_OP].compute_all();
373
        T0 &= DATA_MASK;
308 374
        src = T0;
309 375
        res = (T0 << count) | ((eflags & CC_C) << (count - 1));
310 376
        if (count > 1)
......
315 381
            ((src >> (DATA_BITS - count)) & CC_C);
316 382
        CC_OP = CC_OP_EFLAGS;
317 383
    }
384
    FORCE_RET();
318 385
}
319 386

  
320 387
void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
......
330 397
#endif
331 398
    if (count) {
332 399
        eflags = cc_table[CC_OP].compute_all();
400
        T0 &= DATA_MASK;
333 401
        src = T0;
334 402
        res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
335 403
        if (count > 1)
......
340 408
            ((src >> (count - 1)) & CC_C);
341 409
        CC_OP = CC_OP_EFLAGS;
342 410
    }
411
    FORCE_RET();
343 412
}
344 413

  
345 414
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
......
352 421
        CC_DST = T0;
353 422
        CC_OP = CC_OP_ADDB + SHIFT;
354 423
    } else if (count) {
355
        CC_SRC = T0 >> (DATA_BITS - count);
424
        CC_SRC = (DATA_TYPE)T0 >> (DATA_BITS - count);
356 425
        T0 = T0 << count;
357 426
        CC_DST = T0;
358 427
        CC_OP = CC_OP_SHLB + SHIFT;
359 428
    }
429
    FORCE_RET();
360 430
}
361 431

  
362 432
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
......
370 440
        CC_DST = T0;
371 441
        CC_OP = CC_OP_SHLB + SHIFT;
372 442
    }
443
    FORCE_RET();
373 444
}
374 445

  
375 446
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
......
381 452
        CC_SRC =  src >> (count - 1);
382 453
        T0 = src >> count;
383 454
        CC_DST = T0;
384
        CC_OP = CC_OP_SHLB + SHIFT;
455
        CC_OP = CC_OP_SARB + SHIFT;
385 456
    }
457
    FORCE_RET();
386 458
}
387 459

  
460
/* carry add/sub (we only need to set CC_OP differently) */
461

  
462
void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
463
{
464
    int cf;
465
    cf = cc_table[CC_OP].compute_c();
466
    CC_SRC = T0;
467
    T0 = T0 + T1 + cf;
468
    CC_DST = T0;
469
    CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
470
}
471

  
472
void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
473
{
474
    int cf;
475
    cf = cc_table[CC_OP].compute_c();
476
    CC_SRC = T0;
477
    T0 = T0 - T1 - cf;
478
    CC_DST = T0;
479
    CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
480
}
481

  
482
/* bit operations */
483
#if DATA_BITS >= 16
484

  
485
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
486
{
487
    int count;
488
    count = T1 & SHIFT_MASK;
489
    CC_SRC = T0 >> count;
490
}
491

  
492
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
493
{
494
    int count;
495
    count = T1 & SHIFT_MASK;
496
    CC_SRC = T0 >> count;
497
    T0 |= (1 << count);
498
}
499

  
500
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
501
{
502
    int count;
503
    count = T1 & SHIFT_MASK;
504
    CC_SRC = T0 >> count;
505
    T0 &= ~(1 << count);
506
}
507

  
508
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
509
{
510
    int count;
511
    count = T1 & SHIFT_MASK;
512
    CC_SRC = T0 >> count;
513
    T0 ^= (1 << count);
514
}
515

  
516
#endif
517

  
388 518
/* string operations */
389 519
/* XXX: maybe use lower level instructions to ease exception handling */
390 520

  
......
464 594
{
465 595
    int v;
466 596

  
467
    v = glue(ldu, SUFFIX)((void *)ESI);
468
    ESI += (DF << SHIFT);
597
    v = glue(ldu, SUFFIX)((void *)EDI);
598
    EDI += (DF << SHIFT);
469 599
    CC_SRC = EAX;
470 600
    CC_DST = EAX - v;
471 601
}
......
476 606

  
477 607
    if (ECX != 0) {
478 608
        /* NOTE: the flags are not modified if ECX == 0 */
479
#if SHIFT == 0
480
        v1 = EAX & 0xff;
481
#elif SHIFT == 1
482
        v1 = EAX & 0xffff;
483
#else
484
        v1 = EAX;
485
#endif
609
        v1 = EAX & DATA_MASK;
486 610
        inc = (DF << SHIFT);
487 611
        do {
488
            v2 = glue(ldu, SUFFIX)((void *)ESI);
612
            v2 = glue(ldu, SUFFIX)((void *)EDI);
613
            EDI += inc;
614
            ECX--;
489 615
            if (v1 != v2)
490 616
                break;
491
            ESI += inc;
492
            ECX--;
493 617
        } while (ECX != 0);
494 618
        CC_SRC = v1;
495 619
        CC_DST = v1 - v2;
......
503 627

  
504 628
    if (ECX != 0) {
505 629
        /* NOTE: the flags are not modified if ECX == 0 */
506
#if SHIFT == 0
507
        v1 = EAX & 0xff;
508
#elif SHIFT == 1
509
        v1 = EAX & 0xffff;
510
#else
511
        v1 = EAX;
512
#endif
630
        v1 = EAX & DATA_MASK;
513 631
        inc = (DF << SHIFT);
514 632
        do {
515
            v2 = glue(ldu, SUFFIX)((void *)ESI);
633
            v2 = glue(ldu, SUFFIX)((void *)EDI);
634
            EDI += inc;
635
            ECX--;
516 636
            if (v1 == v2)
517 637
                break;
518
            ESI += inc;
519
            ECX--;
520 638
        } while (ECX != 0);
521 639
        CC_SRC = v1;
522 640
        CC_DST = v1 - v2;
......
543 661
        do {
544 662
            v1 = glue(ldu, SUFFIX)((void *)ESI);
545 663
            v2 = glue(ldu, SUFFIX)((void *)EDI);
546
            if (v1 != v2)
547
                break;
548 664
            ESI += inc;
549 665
            EDI += inc;
550 666
            ECX--;
667
            if (v1 != v2)
668
                break;
551 669
        } while (ECX != 0);
552 670
        CC_SRC = v1;
553 671
        CC_DST = v1 - v2;
......
563 681
        do {
564 682
            v1 = glue(ldu, SUFFIX)((void *)ESI);
565 683
            v2 = glue(ldu, SUFFIX)((void *)EDI);
566
            if (v1 == v2)
567
                break;
568 684
            ESI += inc;
569 685
            EDI += inc;
570 686
            ECX--;
687
            if (v1 == v2)
688
                break;
571 689
        } while (ECX != 0);
572 690
        CC_SRC = v1;
573 691
        CC_DST = v1 - v2;
b/tests/Makefile
20 20

  
21 21
# i386 emulation test (dump various opcodes) */
22 22
test-i386: test-i386.c test-i386.h test-i386-shift.h
23
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
23
	$(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ $<
24 24

  
25 25
test: test-i386
26 26
	./test-i386 > test-i386.ref
b/tests/test-i386.c
14 14
#define CC_S    0x0080
15 15
#define CC_O    0x0800
16 16

  
17
/* XXX: currently no A flag */
18
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
19

  
20 17
#define __init_call	__attribute__ ((unused,__section__ (".initcall.init")))
21 18

  
22 19
static void *call_start __init_call = NULL;
23 20

  
21
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
22

  
24 23
#define OP add
25 24
#include "test-i386.h"
26 25

  
......
67 66
#define OP1
68 67
#include "test-i386.h"
69 68

  
69
#undef CC_MASK
70
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
71

  
70 72
#define OP shl
71 73
#include "test-i386-shift.h"
72 74

  
......
268 270
    TEST_JCC("jns", 0, 0);
269 271
}
270 272

  
273
#undef CC_MASK
274
#define CC_MASK (CC_O | CC_C)
275

  
276
#define OP mul
277
#include "test-i386-muldiv.h"
278

  
279
#define OP imul
280
#include "test-i386-muldiv.h"
281

  
282
#undef CC_MASK
283
#define CC_MASK (0)
284

  
285
#define OP div
286
#include "test-i386-muldiv.h"
287

  
288
#define OP idiv
289
#include "test-i386-muldiv.h"
290

  
291
void test_imulw2(int op0, int op1) 
292
{
293
    int res, s1, s0, flags;
294
    s0 = op0;
295
    s1 = op1;
296
    res = s0;
297
    flags = 0;
298
    asm ("push %4\n\t"
299
         "popf\n\t"
300
         "imulw %w2, %w0\n\t" 
301
         "pushf\n\t"
302
         "popl %1\n\t"
303
         : "=q" (res), "=g" (flags)
304
         : "q" (s1), "0" (res), "1" (flags));
305
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
306
           "imulw", s0, s1, res, flags & CC_MASK);
307
}
308

  
309
void test_imull2(int op0, int op1) 
310
{
311
    int res, s1, s0, flags;
312
    s0 = op0;
313
    s1 = op1;
314
    res = s0;
315
    flags = 0;
316
    asm ("push %4\n\t"
317
         "popf\n\t"
318
         "imull %2, %0\n\t" 
319
         "pushf\n\t"
320
         "popl %1\n\t"
321
         : "=q" (res), "=g" (flags)
322
         : "q" (s1), "0" (res), "1" (flags));
323
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
324
           "imull", s0, s1, res, flags & CC_MASK);
325
}
326

  
327
void test_mul(void)
328
{
329
    test_imulb(0x1234561d, 4);
330
    test_imulb(3, -4);
331
    test_imulb(0x80, 0x80);
332
    test_imulb(0x10, 0x10);
333

  
334
    test_imulw(0, 0x1234001d, 45);
335
    test_imulw(0, 23, -45);
336
    test_imulw(0, 0x8000, 0x8000);
337
    test_imulw(0, 0x100, 0x100);
338

  
339
    test_imull(0, 0x1234001d, 45);
340
    test_imull(0, 23, -45);
341
    test_imull(0, 0x80000000, 0x80000000);
342
    test_imull(0, 0x10000, 0x10000);
343

  
344
    test_mulb(0x1234561d, 4);
345
    test_mulb(3, -4);
346
    test_mulb(0x80, 0x80);
347
    test_mulb(0x10, 0x10);
348

  
349
    test_mulw(0, 0x1234001d, 45);
350
    test_mulw(0, 23, -45);
351
    test_mulw(0, 0x8000, 0x8000);
352
    test_mulw(0, 0x100, 0x100);
353

  
354
    test_mull(0, 0x1234001d, 45);
355
    test_mull(0, 23, -45);
356
    test_mull(0, 0x80000000, 0x80000000);
357
    test_mull(0, 0x10000, 0x10000);
358

  
359
    test_imulw2(0x1234001d, 45);
360
    test_imulw2(23, -45);
361
    test_imulw2(0x8000, 0x8000);
362
    test_imulw2(0x100, 0x100);
363

  
364
    test_imull2(0x1234001d, 45);
365
    test_imull2(23, -45);
366
    test_imull2(0x80000000, 0x80000000);
367
    test_imull2(0x10000, 0x10000);
368

  
369
    test_idivb(0x12341678, 0x127e);
370
    test_idivb(0x43210123, -5);
371
    test_idivb(0x12340004, -1);
372

  
373
    test_idivw(0, 0x12345678, 12347);
374
    test_idivw(0, -23223, -45);
375
    test_idivw(0, 0x12348000, -1);
376
    test_idivw(0x12343, 0x12345678, 0x81238567);
377

  
378
    test_idivl(0, 0x12345678, 12347);
379
    test_idivl(0, -233223, -45);
380
    test_idivl(0, 0x80000000, -1);
381
    test_idivl(0x12343, 0x12345678, 0x81234567);
382

  
383
    test_divb(0x12341678, 0x127e);
384
    test_divb(0x43210123, -5);
385
    test_divb(0x12340004, -1);
386

  
387
    test_divw(0, 0x12345678, 12347);
388
    test_divw(0, -23223, -45);
389
    test_divw(0, 0x12348000, -1);
390
    test_divw(0x12343, 0x12345678, 0x81238567);
391

  
392
    test_divl(0, 0x12345678, 12347);
393
    test_divl(0, -233223, -45);
394
    test_divl(0, 0x80000000, -1);
395
    test_divl(0x12343, 0x12345678, 0x81234567);
396
}
397

  
398

  
271 399
static void *call_end __init_call = NULL;
272 400

  
273 401
int main(int argc, char **argv)
274 402
{
275 403
    void **ptr;
276 404
    void (*func)(void);
405

  
406
    test_mul();
407
#if 0
277 408
    ptr = &call_start + 1;
278 409
    while (*ptr != NULL) {
279 410
        func = *ptr++;
280 411
        func();
281 412
    }
282
    test_lea();
283 413
    test_jcc();
414
    test_lea();
415
#endif
284 416
    return 0;
285 417
}
b/translate-i386.c
27 27
    va_list ap;
28 28

  
29 29
    va_start(ap, fmt);
30
    fprintf(stderr, "\n");
30 31
    vfprintf(stderr, fmt, ap);
32
    fprintf(stderr, "\n");
31 33
    va_end(ap);
32 34
    exit(1);
33 35
}
......
98 100
    OR_EBP,
99 101
    OR_ESI,
100 102
    OR_EDI,
101

  
102
    /* I386 float registers */
103
    OR_ST0,
104
    OR_ST1,
105
    OR_ST2,
106
    OR_ST3,
107
    OR_ST4,
108
    OR_ST5,
109
    OR_ST6,
110
    OR_ST7,
111 103
    OR_TMP0,    /* temporary operand register */
112 104
    OR_TMP1,
113 105
    OR_A0, /* temporary register used when doing address evaluation */
114
    OR_EFLAGS,  /* cpu flags */
115
    OR_ITMP0, /* used for byte/word insertion */
116
    OR_ITMP1, /* used for byte/word insertion */
117
    OR_ITMP2, /* used for byte/word insertion */
118
    OR_FTMP0, /* float temporary */
119
    OR_DF,    /* D flag, for string ops */
120 106
    OR_ZERO, /* fixed zero register */
121
    OR_IM, /* dummy immediate value register */
122 107
    NB_OREGS,
123 108
};
124 109

  
125
#if 0
126
static const double tab_const[7] = {
127
    1.0, 
128
    3.32192809488736234789, /* log2(10) */
129
    M_LOG2E,
130
    M_PI,
131
    0.30102999566398119521, /* log10(2) */
132
    M_LN2,
133
    0.0
134
};
135
#endif
136

  
137 110
typedef void (GenOpFunc)(void);
138 111
typedef void (GenOpFunc1)(long);
139 112
typedef void (GenOpFunc2)(long, long);
......
354 327
static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
355 328
    gen_op_addl_T0_T1_cc,
356 329
    gen_op_orl_T0_T1_cc,
357
    gen_op_adcl_T0_T1_cc,
358
    gen_op_sbbl_T0_T1_cc,
330
    NULL,
331
    NULL,
359 332
    gen_op_andl_T0_T1_cc,
360 333
    gen_op_subl_T0_T1_cc,
361 334
    gen_op_xorl_T0_T1_cc,
362 335
    gen_op_cmpl_T0_T1_cc,
363 336
};
364 337

  
338
static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
339
    [OT_BYTE] = {
340
        gen_op_adcb_T0_T1_cc,
341
        gen_op_sbbb_T0_T1_cc,
342
    },
343
    [OT_WORD] = {
344
        gen_op_adcw_T0_T1_cc,
345
        gen_op_sbbw_T0_T1_cc,
346
    },
347
    [OT_LONG] = {
348
        gen_op_adcl_T0_T1_cc,
349
        gen_op_sbbl_T0_T1_cc,
350
    },
351
};
352

  
365 353
static const int cc_op_arithb[8] = {
366 354
    CC_OP_ADDB,
367 355
    CC_OP_LOGICB,
......
406 394
    },
407 395
};
408 396

  
397
static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
398
    [0] = {
399
        gen_op_btw_T0_T1_cc,
400
        gen_op_btsw_T0_T1_cc,
401
        gen_op_btrw_T0_T1_cc,
402
        gen_op_btcw_T0_T1_cc,
403
    },
404
    [1] = {
405
        gen_op_btl_T0_T1_cc,
406
        gen_op_btsl_T0_T1_cc,
407
        gen_op_btrl_T0_T1_cc,
408
        gen_op_btcl_T0_T1_cc,
409
    },
410
};
411

  
409 412
static GenOpFunc *gen_op_lds_T0_A0[3] = {
410 413
    gen_op_ldsb_T0_A0,
411 414
    gen_op_ldsw_T0_A0,
......
644 647
        gen_op_mov_TN_reg[ot][0][d]();
645 648
    if (s != OR_TMP1)
646 649
        gen_op_mov_TN_reg[ot][1][s]();
647
    if ((op == OP_ADCL || op == OP_SBBL) && s1->cc_op != CC_OP_DYNAMIC)
648
        gen_op_set_cc_op(s1->cc_op);
649
    gen_op_arith_T0_T1_cc[op]();
650
    if (op == OP_ADCL || op == OP_SBBL) {
651
        if (s1->cc_op != CC_OP_DYNAMIC)
652
            gen_op_set_cc_op(s1->cc_op);
653
        gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
654
        s1->cc_op = CC_OP_DYNAMIC;
655
    } else {
656
        gen_op_arith_T0_T1_cc[op]();
657
        s1->cc_op = cc_op_arithb[op] + ot;
658
    }
650 659
    if (d != OR_TMP0 && op != OP_CMPL)
651 660
        gen_op_mov_reg_T0[ot][d]();
652
    s1->cc_op = cc_op_arithb[op] + ot;
653 661
}
654 662

  
655 663
static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
656 664
{
657 665
    gen_op_movl_T1_im(c);
658
    gen_op(s1, op, ot, d, OR_TMP0);
666
    gen_op(s1, op, ot, d, OR_TMP1);
659 667
}
660 668

  
661 669
static void gen_inc(DisasContext *s1, int ot, int d, int c)
......
664 672
        gen_op_mov_TN_reg[ot][0][d]();
665 673
    if (s1->cc_op != CC_OP_DYNAMIC)
666 674
        gen_op_set_cc_op(s1->cc_op);
667
    if (c > 0)
675
    if (c > 0) {
668 676
        gen_op_incl_T0_cc();
669
    else
677
        s1->cc_op = CC_OP_INCB + ot;
678
    } else {
670 679
        gen_op_decl_T0_cc();
680
        s1->cc_op = CC_OP_DECB + ot;
681
    }
671 682
    if (d != OR_TMP0)
672 683
        gen_op_mov_reg_T0[ot][d]();
673 684
}
......
678 689
        gen_op_mov_TN_reg[ot][0][d]();
679 690
    if (s != OR_TMP1)
680 691
        gen_op_mov_TN_reg[ot][1][s]();
681
    switch(op) {
682
    case OP_ROL:
683
    case OP_ROR:
684
    case OP_RCL:
685
    case OP_RCR:
686
        /* only C and O are modified, so we must update flags dynamically */
687
        if (s1->cc_op != CC_OP_DYNAMIC)
688
            gen_op_set_cc_op(s1->cc_op);
689
        gen_op_shift_T0_T1_cc[ot][op]();
690
        break;
691
    default:
692
        gen_op_shift_T0_T1_cc[ot][op]();
693
        break;
694
    }
692
    /* for zero counts, flags are not updated, so must do it dynamically */
693
    if (s1->cc_op != CC_OP_DYNAMIC)
694
        gen_op_set_cc_op(s1->cc_op);
695

  
696
    gen_op_shift_T0_T1_cc[ot][op]();
697

  
695 698
    if (d != OR_TMP0)
696 699
        gen_op_mov_reg_T0[ot][d]();
697 700
    s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
......
785 788
            }
786 789
            gen_op_addl_A0_reg_sN[scale][reg2]();
787 790
        }
788
        opreg = OR_A0;
789 791
    } else {
790
        fprintf(stderr, "16 bit addressing not supported\n");
791
        disp = 0;
792
        opreg = 0;
792
        switch (mod) {
793
        case 0:
794
            if (rm == 6) {
795
                disp = lduw(s->pc);
796
                s->pc += 2;
797
                gen_op_movl_A0_im(disp);
798
                goto no_rm;
799
            } else {
800
                disp = 0;
801
            }
802
            break;
803
        case 1:
804
            disp = (int8_t)ldub(s->pc++);
805
            break;
806
        default:
807
        case 2:
808
            disp = lduw(s->pc);
809
            s->pc += 2;
810
            break;
811
        }
812
        switch(rm) {
813
        case 0:
814
            gen_op_movl_A0_reg[R_EBX]();
815
            gen_op_addl_A0_reg_sN[0][R_ESI]();
816
            break;
817
        case 1:
818
            gen_op_movl_A0_reg[R_EBX]();
819
            gen_op_addl_A0_reg_sN[0][R_EDI]();
820
            break;
821
        case 2:
822
            gen_op_movl_A0_reg[R_EBP]();
823
            gen_op_addl_A0_reg_sN[0][R_ESI]();
824
            break;
825
        case 3:
826
            gen_op_movl_A0_reg[R_EBP]();
827
            gen_op_addl_A0_reg_sN[0][R_EDI]();
828
            break;
829
        case 4:
830
            gen_op_movl_A0_reg[R_ESI]();
831
            break;
832
        case 5:
833
            gen_op_movl_A0_reg[R_EDI]();
834
            break;
835
        case 6:
836
            gen_op_movl_A0_reg[R_EBP]();
837
            break;
838
        default:
839
        case 7:
840
            gen_op_movl_A0_reg[R_EBX]();
841
            break;
842
        }
843
        if (disp != 0)
844
            gen_op_addl_A0_im(disp);
845
        gen_op_andl_A0_ffff();
846
    no_rm: ;
793 847
    }
848
    opreg = OR_A0;
849
    disp = 0;
794 850
    *reg_ptr = opreg;
795 851
    *offset_ptr = disp;
796 852
}
......
870 926
    case CC_OP_ADDB:
871 927
    case CC_OP_ADDW:
872 928
    case CC_OP_ADDL:
929
    case CC_OP_ADCB:
930
    case CC_OP_ADCW:
931
    case CC_OP_ADCL:
932
    case CC_OP_SBBB:
933
    case CC_OP_SBBW:
934
    case CC_OP_SBBL:
873 935
    case CC_OP_LOGICB:
874 936
    case CC_OP_LOGICW:
875 937
    case CC_OP_LOGICL:
......
882 944
    case CC_OP_SHLB:
883 945
    case CC_OP_SHLW:
884 946
    case CC_OP_SHLL:
947
    case CC_OP_SARB:
948
    case CC_OP_SARW:
949
    case CC_OP_SARL:
885 950
        switch(jcc_op) {
886 951
        case JCC_Z:
887 952
            func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
......
1284 1349
            gen_inc(s, ot, OR_TMP0, 1);
1285 1350
            if (mod != 3)
1286 1351
                gen_op_st_T0_A0[ot]();
1352
            else
1353
                gen_op_mov_reg_T0[ot][rm]();
1287 1354
            break;
1288 1355
        case 1: /* dec Ev */
1289 1356
            gen_inc(s, ot, OR_TMP0, -1);
1290 1357
            if (mod != 3)
1291 1358
                gen_op_st_T0_A0[ot]();
1359
            else
1360
                gen_op_mov_reg_T0[ot][rm]();
1292 1361
            break;
1293 1362
        case 2: /* call Ev */
1294 1363
            gen_op_movl_T1_im((long)s->pc);
......
1359 1428
        ot = dflag ? OT_LONG : OT_WORD;
1360 1429
        modrm = ldub(s->pc++);
1361 1430
        reg = ((modrm >> 3) & 7) + OR_EAX;
1362
        
1363 1431
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1364 1432
        if (b == 0x69) {
1365 1433
            val = insn_get(s, ot);
......
1372 1440
        }
1373 1441

  
1374 1442
        if (ot == OT_LONG) {
1375
            op_imull_T0_T1();
1443
            gen_op_imull_T0_T1();
1376 1444
        } else {
1377
            op_imulw_T0_T1();
1445
            gen_op_imulw_T0_T1();
1378 1446
        }
1379 1447
        gen_op_mov_reg_T0[ot][reg]();
1380 1448
        s->cc_op = CC_OP_MUL;
......
1522 1590
            offset_addr = insn_get(s, OT_LONG);
1523 1591
        else
1524 1592
            offset_addr = insn_get(s, OT_WORD);
1525
            
1593
        gen_op_movl_A0_im(offset_addr);
1526 1594
        if ((b & 2) == 0) {
1527 1595
            gen_op_ld_T0_A0[ot]();
1528 1596
            gen_op_mov_reg_T0[ot][R_EAX]();
......
1717 1785
                    break;
1718 1786
                }
1719 1787
                break;
1720
#if 0
1788
            case 0x0d: /* fldcw mem */
1789
                gen_op_fldcw_A0();
1790
                break;
1791
            case 0x0f: /* fnstcw mem */
1792
                gen_op_fnstcw_A0();
1793
                break;
1721 1794
            case 0x2f: /* fnstsw mem */
1722
                gen_insn3(OP_FNSTS, OR_TMP0, OR_ZERO, OR_ZERO);
1723
                gen_st(OP_STW, OR_TMP0, reg_addr, offset_addr);
1795
                gen_op_fnstsw_A0();
1724 1796
                break;
1725

  
1726 1797
            case 0x3c: /* fbld */
1727 1798
            case 0x3e: /* fbstp */
1728 1799
                error("float BCD not hanlded");
1729 1800
                return -1;
1730
#endif
1731 1801
            case 0x3d: /* fildll */
1732 1802
                gen_op_fpush();
1733 1803
                gen_op_fildll_ST0_A0();
......
1737 1807
                gen_op_fpop();
1738 1808
                break;
1739 1809
            default:
1740
                error("unhandled memory FP\n");
1810
                error("unhandled memory FP [op=0x%02x]\n", op);
1741 1811
                return -1;
1742 1812
            }
1743 1813
        } else {
......
1987 2057
        else
1988 2058
            ot = dflag ? OT_LONG : OT_WORD;
1989 2059
        if (prefixes & PREFIX_REPNZ) {
2060
            if (s->cc_op != CC_OP_DYNAMIC)
2061
                gen_op_set_cc_op(s->cc_op);
1990 2062
            gen_op_scas[6 + ot]();
2063
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1991 2064
        } else if (prefixes & PREFIX_REPZ) {
2065
            if (s->cc_op != CC_OP_DYNAMIC)
2066
                gen_op_set_cc_op(s->cc_op);
1992 2067
            gen_op_scas[3 + ot]();
2068
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1993 2069
        } else {
1994 2070
            gen_op_scas[ot]();
2071
            s->cc_op = CC_OP_SUBB + ot;
1995 2072
        }
1996 2073
        break;
1997 2074

  
......
2002 2079
        else
2003 2080
            ot = dflag ? OT_LONG : OT_WORD;
2004 2081
        if (prefixes & PREFIX_REPNZ) {
2082
            if (s->cc_op != CC_OP_DYNAMIC)
2083
                gen_op_set_cc_op(s->cc_op);
2005 2084
            gen_op_cmps[6 + ot]();
2085
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2006 2086
        } else if (prefixes & PREFIX_REPZ) {
2087
            if (s->cc_op != CC_OP_DYNAMIC)
2088
                gen_op_set_cc_op(s->cc_op);
2007 2089
            gen_op_cmps[3 + ot]();
2090
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2008 2091
        } else {
2009 2092
            gen_op_cmps[ot]();
2093
            s->cc_op = CC_OP_SUBB + ot;
2010 2094
        }
2011 2095
        break;
2012 2096
        
......
2187 2271
        break;
2188 2272

  
2189 2273
        /************************/
2274
        /* bit operations */
2275
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
2276
        ot = dflag ? OT_LONG : OT_WORD;
2277
        modrm = ldub(s->pc++);
2278
        op = (modrm >> 3) & 7;
2279
        mod = (modrm >> 6) & 3;
2280
        rm = modrm & 7;
2281
        if (mod != 3) {
2282
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2283
            gen_op_ld_T0_A0[ot]();
2284
        } else {
2285
            gen_op_mov_TN_reg[ot][0][rm]();
2286
        }
2287
        /* load shift */
2288
        val = ldub(s->pc++);
2289
        gen_op_movl_T1_im(val);
2290
        if (op < 4)
2291
            return -1;
2292
        op -= 4;
2293
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2294
        s->cc_op = CC_OP_SHLB + ot;
2295
        if (op != 0) {
2296
            if (mod != 3)
2297
                gen_op_st_T0_A0[ot]();
2298
            else
2299
                gen_op_mov_reg_T0[ot][rm]();
2300
        }
2301
        break;
2302
    case 0x1a3: /* bt Gv, Ev */
2303
        op = 0;
2304
        goto do_btx;
2305
    case 0x1ab: /* bts */
2306
        op = 1;
2307
        goto do_btx;
2308
    case 0x1b3: /* btr */
2309
        op = 2;
2310
        goto do_btx;
2311
    case 0x1bb: /* btc */
2312
        op = 3;
2313
    do_btx:
2314
        ot = dflag ? OT_LONG : OT_WORD;
2315
        modrm = ldub(s->pc++);
2316
        reg = (modrm >> 3) & 7;
2317
        mod = (modrm >> 6) & 3;
2318
        rm = modrm & 7;
2319
        gen_op_mov_TN_reg[OT_LONG][1][reg]();
2320
        if (mod != 3) {
2321
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2322
            /* specific case: we need to add a displacement */
2323
            if (ot == OT_WORD)
2324
                gen_op_add_bitw_A0_T1();
2325
            else
2326
                gen_op_add_bitl_A0_T1();
2327
            gen_op_ld_T0_A0[ot]();
2328
        } else {
2329
            gen_op_mov_TN_reg[ot][0][rm]();
2330
        }
2331
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2332
        s->cc_op = CC_OP_SHLB + ot;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff