Revision d57c4e01

b/Makefile
84 84
dis-buf.c    i386-dis.c  opreg_template.h  syscall_defs.h\
85 85
i386.ld ppc.ld\
86 86
tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\
87
tests/test-i386-muldiv.h\
87 88
tests/test2.c tests/hello.c tests/sha1.c tests/test1.c
88 89

  
89 90
FILE=gemu-$(VERSION)
b/cpu-i386.h
149 149
    uint32_t segs[6];
150 150

  
151 151
    /* emulator internal variables */
152
    
153 152
    CPU86_LDouble ft0;
154

  
153
    
155 154
    /* exception handling */
156 155
    jmp_buf jmp_env;
157 156
    int exception_index;
b/ops_template.h
175 175
static int glue(compute_all_shl, SUFFIX)(void)
176 176
{
177 177
    int cf, pf, af, zf, sf, of;
178
    cf = CC_SRC & 1;
178
    cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
179 179
    pf = parity_table[(uint8_t)CC_DST];
180 180
    af = 0; /* undefined */
181 181
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
182 182
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
183
    of = lshift(CC_SRC, 12 - DATA_BITS) & CC_O; /* only meaniful for shr with count == 1 */
183
    /* of is defined if shift count == 1 */
184
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
184 185
    return cf | pf | af | zf | sf | of;
185 186
}
186 187

  
......
199 200
    af = 0; /* undefined */
200 201
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
201 202
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
202
    of = 0; /* only meaniful for shr with count == 1 */
203
    /* of is defined if shift count == 1 */
204
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O; 
203 205
    return cf | pf | af | zf | sf | of;
204 206
}
205 207

  
......
415 417
{
416 418
    int count;
417 419
    count = T1 & 0x1f;
418
    if (count == 1) {
419
        CC_SRC = T0;
420
        T0 = T0 << 1;
421
        CC_DST = T0;
422
        CC_OP = CC_OP_ADDB + SHIFT;
423
    } else if (count) {
424
        CC_SRC = (DATA_TYPE)T0 >> (DATA_BITS - count);
420
    if (count) {
421
        CC_SRC = (DATA_TYPE)T0 << (count - 1);
425 422
        T0 = T0 << count;
426 423
        CC_DST = T0;
427 424
        CC_OP = CC_OP_SHLB + SHIFT;
......
438 435
        CC_SRC = T0 >> (count - 1);
439 436
        T0 = T0 >> count;
440 437
        CC_DST = T0;
441
        CC_OP = CC_OP_SHLB + SHIFT;
438
        CC_OP = CC_OP_SARB + SHIFT;
442 439
    }
443 440
    FORCE_RET();
444 441
}
......
449 446
    count = T1 & 0x1f;
450 447
    if (count) {
451 448
        src = (DATA_STYPE)T0;
452
        CC_SRC =  src >> (count - 1);
449
        CC_SRC = src >> (count - 1);
453 450
        T0 = src >> count;
454 451
        CC_DST = T0;
455 452
        CC_OP = CC_OP_SARB + SHIFT;
......
457 454
    FORCE_RET();
458 455
}
459 456

  
457
#if DATA_BITS == 16
458
/* XXX: overflow flag might be incorrect in some cases in shldw */
459
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
460
{
461
    int count;
462
    unsigned int res;
463
    count = PARAM1;
464
    T1 &= 0xffff;
465
    res = T1 | (T0 << 16);
466
    CC_SRC = res >> (32 - count);
467
    res <<= count;
468
    if (count > 16)
469
        res |= T1 << (count - 16);
470
    T0 = res >> 16;
471
    CC_DST = T0;
472
}
473

  
474
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
475
{
476
    int count;
477
    unsigned int res;
478
    count = ECX & 0x1f;
479
    if (count) {
480
        T1 &= 0xffff;
481
        res = T1 | (T0 << 16);
482
        CC_SRC = res >> (32 - count);
483
        res <<= count;
484
        if (count > 16)
485
          res |= T1 << (count - 16);
486
        T0 = res >> 16;
487
        CC_DST = T0;
488
        CC_OP = CC_OP_SARB + SHIFT;
489
    }
490
}
491

  
492
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
493
{
494
    int count;
495
    unsigned int res;
496

  
497
    count = PARAM1;
498
    res = (T0 & 0xffff) | (T1 << 16);
499
    CC_SRC = res >> (count - 1);
500
    res >>= count;
501
    if (count > 16)
502
        res |= T1 << (32 - count);
503
    T0 = res;
504
    CC_DST = T0;
505
}
506

  
507

  
508
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
509
{
510
    int count;
511
    unsigned int res;
512

  
513
    count = ECX & 0x1f;
514
    if (count) {
515
        res = (T0 & 0xffff) | (T1 << 16);
516
        CC_SRC = res >> (count - 1);
517
        res >>= count;
518
        if (count > 16)
519
            res |= T1 << (32 - count);
520
        T0 = res;
521
        CC_DST = T0;
522
        CC_OP = CC_OP_SARB + SHIFT;
523
    }
524
}
525
#endif
526

  
527
#if DATA_BITS == 32
528
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
529
{
530
    int count;
531
    count = PARAM1;
532
    T0 &= DATA_MASK;
533
    T1 &= DATA_MASK;
534
    CC_SRC = T0 << (count - 1);
535
    T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
536
    CC_DST = T0;
537
}
538

  
539
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
540
{
541
    int count;
542
    count = ECX & 0x1f;
543
    if (count) {
544
        T0 &= DATA_MASK;
545
        T1 &= DATA_MASK;
546
        CC_SRC = T0 << (count - 1);
547
        T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
548
        CC_DST = T0;
549
        CC_OP = CC_OP_SHLB + SHIFT;
550
    }
551
}
552

  
553
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
554
{
555
    int count;
556
    count = PARAM1;
557
    T0 &= DATA_MASK;
558
    T1 &= DATA_MASK;
559
    CC_SRC = T0 >> (count - 1);
560
    T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
561
    CC_DST = T0;
562
}
563

  
564

  
565
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
566
{
567
    int count;
568
    count = ECX & 0x1f;
569
    if (count) {
570
        T0 &= DATA_MASK;
571
        T1 &= DATA_MASK;
572
        CC_SRC = T0 >> (count - 1);
573
        T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
574
        CC_DST = T0;
575
        CC_OP = CC_OP_SARB + SHIFT;
576
    }
577
}
578
#endif
579

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

  
462 582
void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
b/tests/Makefile
19 19
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
20 20

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

  
25 25
test: test-i386
b/tests/test-i386-muldiv.h
1

  
2
void glue(glue(test_, OP), b)(int op0, int op1) 
3
{
4
    int res, s1, s0, flags;
5
    s0 = op0;
6
    s1 = op1;
7
    res = s0;
8
    flags = 0;
9
    asm ("push %4\n\t"
10
         "popf\n\t"
11
         stringify(OP)"b %b2\n\t" 
12
         "pushf\n\t"
13
         "popl %1\n\t"
14
         : "=a" (res), "=g" (flags)
15
         : "q" (s1), "0" (res), "1" (flags));
16
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
17
           stringify(OP) "b", s0, s1, res, flags & CC_MASK);
18
}
19

  
20
void glue(glue(test_, OP), w)(int op0h, int op0, int op1) 
21
{
22
    int res, s1, flags, resh;
23
    s1 = op1;
24
    resh = op0h;
25
    res = op0;
26
    flags = 0;
27
    asm ("push %5\n\t"
28
         "popf\n\t"
29
         stringify(OP) "w %w3\n\t" 
30
         "pushf\n\t"
31
         "popl %1\n\t"
32
         : "=a" (res), "=g" (flags), "=d" (resh)
33
         : "q" (s1), "0" (res), "1" (flags), "2" (resh));
34
    printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n",
35
           stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK);
36
}
37

  
38
void glue(glue(test_, OP), l)(int op0h, int op0, int op1) 
39
{
40
    int res, s1, flags, resh;
41
    s1 = op1;
42
    resh = op0h;
43
    res = op0;
44
    flags = 0;
45
    asm ("push %5\n\t"
46
         "popf\n\t"
47
         stringify(OP) "l %3\n\t" 
48
         "pushf\n\t"
49
         "popl %1\n\t"
50
         : "=a" (res), "=g" (flags), "=d" (resh)
51
         : "q" (s1), "0" (res), "1" (flags), "2" (resh));
52
    printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n",
53
           stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK);
54
}
55

  
56
#undef OP
b/tests/test-i386-shift.h
4 4
#define exec_opw glue(glue(exec_, OP), w)
5 5
#define exec_opb glue(glue(exec_, OP), b)
6 6

  
7
#define EXECSHIFT(size, res, s1, flags) \
7
#ifndef OP_SHIFTD
8

  
9
#ifdef OP_NOBYTE
10
#define EXECSHIFT(size, res, s1, s2, flags) \
11
    asm ("push %4\n\t"\
12
         "popf\n\t"\
13
         stringify(OP) size " %" size "2, %" size "0\n\t" \
14
         "pushf\n\t"\
15
         "popl %1\n\t"\
16
         : "=g" (res), "=g" (flags)\
17
         : "r" (s1), "0" (res), "1" (flags));
18
#else
19
#define EXECSHIFT(size, res, s1, s2, flags) \
8 20
    asm ("push %4\n\t"\
9 21
         "popf\n\t"\
10 22
         stringify(OP) size " %%cl, %" size "0\n\t" \
......
12 24
         "popl %1\n\t"\
13 25
         : "=q" (res), "=g" (flags)\
14 26
         : "c" (s1), "0" (res), "1" (flags));
27
#endif
15 28

  
16
void exec_opl(int s0, int s1, int iflags)
29
void exec_opl(int s2, int s0, int s1, int iflags)
17 30
{
18 31
    int res, flags;
19 32
    res = s0;
20 33
    flags = iflags;
21
    EXECSHIFT("", res, s1, flags);
34
    EXECSHIFT("", res, s1, s2, flags);
22 35
    /* overflow is undefined if count != 1 */
23 36
    if (s1 != 1)
24 37
      flags &= ~CC_O;
......
26 39
           stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
27 40
}
28 41

  
29
void exec_opw(int s0, int s1, int iflags)
42
void exec_opw(int s2, int s0, int s1, int iflags)
30 43
{
31 44
    int res, flags;
32 45
    res = s0;
33 46
    flags = iflags;
34
    EXECSHIFT("w", res, s1, flags);
47
    EXECSHIFT("w", res, s1, s2, flags);
35 48
    /* overflow is undefined if count != 1 */
36 49
    if (s1 != 1)
37 50
      flags &= ~CC_O;
......
39 52
           stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
40 53
}
41 54

  
55
#else
56
#define EXECSHIFT(size, res, s1, s2, flags) \
57
    asm ("push %4\n\t"\
58
         "popf\n\t"\
59
         stringify(OP) size " %%cl, %" size "5, %" size "0\n\t" \
60
         "pushf\n\t"\
61
         "popl %1\n\t"\
62
         : "=g" (res), "=g" (flags)\
63
         : "c" (s1), "0" (res), "1" (flags), "r" (s2));
64

  
65
void exec_opl(int s2, int s0, int s1, int iflags)
66
{
67
    int res, flags;
68
    res = s0;
69
    flags = iflags;
70
    EXECSHIFT("", res, s1, s2, flags);
71
    /* overflow is undefined if count != 1 */
72
    if (s1 != 1)
73
      flags &= ~CC_O;
74
    printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n",
75
           stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
76
}
77

  
78
void exec_opw(int s2, int s0, int s1, int iflags)
79
{
80
    int res, flags;
81
    res = s0;
82
    flags = iflags;
83
    EXECSHIFT("w", res, s1, s2, flags);
84
    /* overflow is undefined if count != 1 */
85
    if (s1 != 1)
86
      flags &= ~CC_O;
87
    printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n",
88
           stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
89
}
90

  
91
#endif
92

  
93
#ifndef OP_NOBYTE
42 94
void exec_opb(int s0, int s1, int iflags)
43 95
{
44 96
    int res, flags;
45 97
    res = s0;
46 98
    flags = iflags;
47
    EXECSHIFT("b", res, s1, flags);
99
    EXECSHIFT("b", res, s1, 0, flags);
48 100
    /* overflow is undefined if count != 1 */
49 101
    if (s1 != 1)
50 102
      flags &= ~CC_O;
51 103
    printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
52 104
           stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
53 105
}
106
#endif
54 107

  
55
void exec_op(int s0, int s1)
108
void exec_op(int s2, int s0, int s1)
56 109
{
57
    exec_opl(s0, s1, 0);
58
    exec_opw(s0, s1, 0);
110
    exec_opl(s2, s0, s1, 0);
111
    exec_opw(s2, s0, s1, 0);
112
#ifndef OP_NOBYTE
59 113
    exec_opb(s0, s1, 0);
114
#endif
60 115
#ifdef OP_CC
61
    exec_opl(s0, s1, CC_C);
62
    exec_opw(s0, s1, CC_C);
116
    exec_opl(s2, s0, s1, CC_C);
117
    exec_opw(s2, s0, s1, CC_C);
63 118
    exec_opb(s0, s1, CC_C);
64 119
#endif
65 120
}
......
68 123
{
69 124
    int i;
70 125
    for(i = 0; i < 32; i++)
71
        exec_op(0x12345678, i);
126
        exec_op(0x21ad3d34, 0x12345678, i);
72 127
    for(i = 0; i < 32; i++)
73
        exec_op(0x82345678, i);
128
        exec_op(0x813f3421, 0x82345678, i);
74 129
}
75 130

  
76 131
void *glue(_test_, OP) __init_call = glue(test_, OP);
77 132

  
78 133
#undef OP
79 134
#undef OP_CC
135
#undef OP_SHIFTD
136
#undef OP_NOBYTE
137
#undef EXECSHIFT
138

  
b/tests/test-i386.c
92 92
#define OP_CC
93 93
#include "test-i386-shift.h"
94 94

  
95
#define OP shld
96
#define OP_SHIFTD
97
#define OP_NOBYTE
98
#include "test-i386-shift.h"
99

  
100
#define OP shrd
101
#define OP_SHIFTD
102
#define OP_NOBYTE
103
#include "test-i386-shift.h"
104

  
105
/* XXX: should be more precise ? */
106
#undef CC_MASK
107
#define CC_MASK (CC_C)
108

  
109
#define OP bt
110
#define OP_NOBYTE
111
#include "test-i386-shift.h"
112

  
113
#define OP bts
114
#define OP_NOBYTE
115
#include "test-i386-shift.h"
116

  
117
#define OP btr
118
#define OP_NOBYTE
119
#include "test-i386-shift.h"
120

  
121
#define OP btc
122
#define OP_NOBYTE
123
#include "test-i386-shift.h"
95 124

  
96 125
/* lea test (modrm support) */
97 126
#define TEST_LEA(STR)\
......
403 432
    void **ptr;
404 433
    void (*func)(void);
405 434

  
406
    test_mul();
407
#if 0
408 435
    ptr = &call_start + 1;
409 436
    while (*ptr != NULL) {
410 437
        func = *ptr++;
411 438
        func();
412 439
    }
440
    test_mul();
413 441
    test_jcc();
414 442
    test_lea();
415
#endif
416 443
    return 0;
417 444
}
b/tests/test-i386.h
1

  
2
#define exec_op glue(exec_, OP)
3
#define exec_opl glue(glue(exec_, OP), l)
4
#define exec_opw glue(glue(exec_, OP), w)
5
#define exec_opb glue(glue(exec_, OP), b)
6

  
7
#define EXECOP2(size, res, s1, flags) \
8
    asm ("push %4\n\t"\
9
         "popf\n\t"\
10
         stringify(OP) size " %" size "2, %" size "0\n\t" \
11
         "pushf\n\t"\
12
         "popl %1\n\t"\
13
         : "=q" (res), "=g" (flags)\
14
         : "q" (s1), "0" (res), "1" (flags));
15

  
16
#define EXECOP1(size, res, flags) \
17
    asm ("push %3\n\t"\
18
         "popf\n\t"\
19
         stringify(OP) size " %" size "0\n\t" \
20
         "pushf\n\t"\
21
         "popl %1\n\t"\
22
         : "=q" (res), "=g" (flags)\
23
         : "0" (res), "1" (flags));
24

  
25
#ifdef OP1
26
void exec_opl(int s0, int s1, int iflags)
27
{
28
    int res, flags;
29
    res = s0;
30
    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);
84
}
85
#endif
86

  
87
void exec_op(int s0, int s1)
88
{
89
    exec_opl(s0, s1, 0);
90
    exec_opw(s0, s1, 0);
91
    exec_opb(s0, s1, 0);
92
#ifdef OP_CC
93
    exec_opl(s0, s1, CC_C);
94
    exec_opw(s0, s1, CC_C);
95
    exec_opb(s0, s1, CC_C);
96
#endif
97
}
98

  
99
void glue(test_, OP)(void)
100
{
101
    exec_op(0x12345678, 0x812FADA);
102
    exec_op(0x12341, 0x12341);
103
    exec_op(0x12341, -0x12341);
104
    exec_op(0xffffffff, 0);
105
    exec_op(0xffffffff, -1);
106
    exec_op(0xffffffff, 1);
107
    exec_op(0xffffffff, 2);
108
    exec_op(0x7fffffff, 0);
109
    exec_op(0x7fffffff, 1);
110
    exec_op(0x7fffffff, -1);
111
    exec_op(0x80000000, -1);
112
    exec_op(0x80000000, 1);
113
    exec_op(0x80000000, -2);
114
    exec_op(0x12347fff, 0);
115
    exec_op(0x12347fff, 1);
116
    exec_op(0x12347fff, -1);
117
    exec_op(0x12348000, -1);
118
    exec_op(0x12348000, 1);
119
    exec_op(0x12348000, -2);
120
    exec_op(0x12347f7f, 0);
121
    exec_op(0x12347f7f, 1);
122
    exec_op(0x12347f7f, -1);
123
    exec_op(0x12348080, -1);
124
    exec_op(0x12348080, 1);
125
    exec_op(0x12348080, -2);
126
}
127

  
128
void *glue(_test_, OP) __init_call = glue(test_, OP);
129

  
130
#undef OP
131
#undef OP_CC
b/translate-i386.c
394 394
    },
395 395
};
396 396

  
397
static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = {
398
    [0] = {
399
        gen_op_shldw_T0_T1_im_cc,
400
        gen_op_shrdw_T0_T1_im_cc,
401
    },
402
    [1] = {
403
        gen_op_shldl_T0_T1_im_cc,
404
        gen_op_shrdl_T0_T1_im_cc,
405
    },
406
};
407

  
408
static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = {
409
    [0] = {
410
        gen_op_shldw_T0_T1_ECX_cc,
411
        gen_op_shrdw_T0_T1_ECX_cc,
412
    },
413
    [1] = {
414
        gen_op_shldl_T0_T1_ECX_cc,
415
        gen_op_shrdl_T0_T1_ECX_cc,
416
    },
417
};
418

  
397 419
static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
398 420
    [0] = {
399 421
        gen_op_btw_T0_T1_cc,
......
1689 1711
        shift = 0;
1690 1712
        goto grp2;
1691 1713

  
1714
    case 0x1a4: /* shld imm */
1715
        op = 0;
1716
        shift = 1;
1717
        goto do_shiftd;
1718
    case 0x1a5: /* shld cl */
1719
        op = 0;
1720
        shift = 0;
1721
        goto do_shiftd;
1722
    case 0x1ac: /* shrd imm */
1723
        op = 1;
1724
        shift = 1;
1725
        goto do_shiftd;
1726
    case 0x1ad: /* shrd cl */
1727
        op = 1;
1728
        shift = 0;
1729
    do_shiftd:
1730
        ot = dflag ? OT_LONG : OT_WORD;
1731
        modrm = ldub(s->pc++);
1732
        mod = (modrm >> 6) & 3;
1733
        rm = modrm & 7;
1734
        reg = (modrm >> 3) & 7;
1735
        
1736
        if (mod != 3) {
1737
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1738
            gen_op_ld_T0_A0[ot]();
1739
        } else {
1740
            gen_op_mov_TN_reg[ot][0][rm]();
1741
        }
1742
        gen_op_mov_TN_reg[ot][1][reg]();
1743
        
1744
        if (shift) {
1745
            val = ldub(s->pc++);
1746
            val &= 0x1f;
1747
            if (val) {
1748
                gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
1749
                if (op == 0 && ot != OT_WORD)
1750
                    s->cc_op = CC_OP_SHLB + ot;
1751
                else
1752
                    s->cc_op = CC_OP_SARB + ot;
1753
            }
1754
        } else {
1755
            if (s->cc_op != CC_OP_DYNAMIC)
1756
                gen_op_set_cc_op(s->cc_op);
1757
            gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
1758
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1759
        }
1760
        if (mod != 3) {
1761
            gen_op_st_T0_A0[ot]();
1762
        } else {
1763
            gen_op_mov_reg_T0[ot][rm]();
1764
        }
1765
        break;
1766

  
1692 1767
        /************************/
1693 1768
        /* floats */
1694 1769
    case 0xd8 ... 0xdf: 
......
2002 2077
                    break;
2003 2078
#endif
2004 2079
                default:
2080
                    error("unhandled FP df/4\n");
2005 2081
                    return -1;
2006 2082
                }
2007 2083
                break;
......
2291 2367
            return -1;
2292 2368
        op -= 4;
2293 2369
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2294
        s->cc_op = CC_OP_SHLB + ot;
2370
        s->cc_op = CC_OP_SARB + ot;
2295 2371
        if (op != 0) {
2296 2372
            if (mod != 3)
2297 2373
                gen_op_st_T0_A0[ot]();
......
2329 2405
            gen_op_mov_TN_reg[ot][0][rm]();
2330 2406
        }
2331 2407
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2332
        s->cc_op = CC_OP_SHLB + ot;
2408
        s->cc_op = CC_OP_SARB + ot;
2333 2409
        if (op != 0) {
2334 2410
            if (mod != 3)
2335 2411
                gen_op_st_T0_A0[ot]();
......
2417 2493
    is_jmp = 0;
2418 2494
    ret = disas_insn(dc, pc_start, &is_jmp);
2419 2495
    if (ret == -1) 
2420
        error("unknown instruction at PC=0x%x", pc_start);
2496
        error("unknown instruction at PC=0x%x B=%02x %02x", 
2497
              pc_start, pc_start[0], pc_start[1]);
2421 2498
    /* we must store the eflags state if it is not already done */
2422 2499
    if (dc->cc_op != CC_OP_DYNAMIC)
2423 2500
        gen_op_set_cc_op(dc->cc_op);

Also available in: Unified diff