Commit d57c4e01206ebc8b21702c243e7a19638f783b43

Authored by bellard
1 parent 4b74fe1f

added shiftd support - improved auto test


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@20 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -84,6 +84,7 @@ dis-asm.h gen-i386.h op-i386.h syscall.c\
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)
... ...
cpu-i386.h
... ... @@ -149,9 +149,8 @@ typedef struct CPUX86State {
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;
... ...
ops_template.h
... ... @@ -175,12 +175,13 @@ static int glue(compute_all_dec, SUFFIX)(void)
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,7 +200,8 @@ static int glue(compute_all_sar, SUFFIX)(void)
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,13 +417,8 @@ void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
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,7 +435,7 @@ void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
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,7 +446,7 @@ void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
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,6 +454,129 @@ void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
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)
... ...
tests/Makefile
... ... @@ -19,7 +19,7 @@ test2: test2.c
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
... ...
tests/test-i386-muldiv.h 0 โ†’ 100644
  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
... ...
tests/test-i386-shift.h
... ... @@ -4,7 +4,19 @@
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,13 +24,14 @@
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,12 +39,12 @@ void exec_opl(int s0, int s1, int iflags)
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,27 +52,69 @@ void exec_opw(int s0, int s1, int iflags)
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,12 +123,16 @@ void glue(test_, OP)(void)
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 +
... ...
tests/test-i386.c
... ... @@ -92,6 +92,35 @@ static void *call_start __init_call = NULL;
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,15 +432,13 @@ int main(int argc, char **argv)
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 }
... ...
tests/test-i386.h 0 โ†’ 100644
  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
... ...
translate-i386.c
... ... @@ -394,6 +394,28 @@ static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
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,6 +1711,59 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
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,6 +2077,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
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,7 +2367,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
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,7 +2405,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
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,7 +2493,8 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr,
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);
... ...