Commit e477b8b81ba5212747799ce71858e2b110fc6ae5

Authored by bellard
1 parent b118d61e

correct eflags evaluation order for all operations - fixed important CPU state r…

…estoring bug in some exception cases - disabled unsafe inc flags optimisation


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@303 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
@@ -174,7 +174,7 @@ op-$(TARGET_ARCH).o: op-$(TARGET_ARCH).c @@ -174,7 +174,7 @@ op-$(TARGET_ARCH).o: op-$(TARGET_ARCH).c
174 helper-$(TARGET_ARCH).o: helper-$(TARGET_ARCH).c 174 helper-$(TARGET_ARCH).o: helper-$(TARGET_ARCH).c
175 $(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $< 175 $(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<
176 176
177 -op-i386.o: op-i386.c opreg_template.h ops_template.h 177 +op-i386.o: op-i386.c opreg_template.h ops_template.h ops_template_mem.h
178 178
179 op-arm.o: op-arm.c op-arm-template.h 179 op-arm.o: op-arm.c op-arm-template.h
180 180
dyngen.c
@@ -1200,11 +1200,11 @@ int load_elf(const char *filename, FILE *outfile, int out_type) @@ -1200,11 +1200,11 @@ int load_elf(const char *filename, FILE *outfile, int out_type)
1200 } 1200 }
1201 1201
1202 if (out_type == OUT_INDEX_OP) { 1202 if (out_type == OUT_INDEX_OP) {
1203 - fprintf(outfile, "DEF(nop1, 0, 0)\n");  
1204 - fprintf(outfile, "DEF(nop2, 0, 0)\n");  
1205 - fprintf(outfile, "DEF(nop3, 0, 0)\n");  
1206 - fprintf(outfile, "DEF(nop, 0, 0)\n");  
1207 fprintf(outfile, "DEF(end, 0, 0)\n"); 1203 fprintf(outfile, "DEF(end, 0, 0)\n");
  1204 + fprintf(outfile, "DEF(nop, 0, 0)\n");
  1205 + fprintf(outfile, "DEF(nop1, 1, 0)\n");
  1206 + fprintf(outfile, "DEF(nop2, 2, 0)\n");
  1207 + fprintf(outfile, "DEF(nop3, 3, 0)\n");
1208 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { 1208 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
1209 const char *name, *p; 1209 const char *name, *p;
1210 name = strtab + sym->st_name; 1210 name = strtab + sym->st_name;
ops_template.h
@@ -406,127 +406,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) @@ -406,127 +406,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
406 406
407 /* shifts */ 407 /* shifts */
408 408
409 -void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)  
410 -{  
411 - int count, src;  
412 - count = T1 & SHIFT_MASK;  
413 - if (count) {  
414 - CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);  
415 - src = T0;  
416 - T0 &= DATA_MASK;  
417 - T0 = (T0 << count) | (T0 >> (DATA_BITS - count));  
418 - CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |  
419 - (T0 & CC_C);  
420 - CC_OP = CC_OP_EFLAGS;  
421 - }  
422 - FORCE_RET();  
423 -}  
424 -  
425 -void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1)(void)  
426 -{  
427 - int count;  
428 - count = T1 & SHIFT_MASK;  
429 - if (count) {  
430 - T0 &= DATA_MASK;  
431 - T0 = (T0 << count) | (T0 >> (DATA_BITS - count));  
432 - }  
433 - FORCE_RET();  
434 -}  
435 -  
436 -void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)  
437 -{  
438 - int count, src;  
439 - count = T1 & SHIFT_MASK;  
440 - if (count) {  
441 - CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);  
442 - src = T0;  
443 - T0 &= DATA_MASK;  
444 - T0 = (T0 >> count) | (T0 << (DATA_BITS - count));  
445 - CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |  
446 - ((T0 >> (DATA_BITS - 1)) & CC_C);  
447 - CC_OP = CC_OP_EFLAGS;  
448 - }  
449 - FORCE_RET();  
450 -}  
451 -  
452 -void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1)(void)  
453 -{  
454 - int count;  
455 - count = T1 & SHIFT_MASK;  
456 - if (count) {  
457 - T0 &= DATA_MASK;  
458 - T0 = (T0 >> count) | (T0 << (DATA_BITS - count));  
459 - }  
460 - FORCE_RET();  
461 -}  
462 -  
463 -void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)  
464 -{  
465 - int count, res, eflags;  
466 - unsigned int src;  
467 -  
468 - count = T1 & 0x1f;  
469 -#if DATA_BITS == 16  
470 - count = rclw_table[count];  
471 -#elif DATA_BITS == 8  
472 - count = rclb_table[count];  
473 -#endif  
474 - if (count) {  
475 - eflags = cc_table[CC_OP].compute_all();  
476 - T0 &= DATA_MASK;  
477 - src = T0;  
478 - res = (T0 << count) | ((eflags & CC_C) << (count - 1));  
479 - if (count > 1)  
480 - res |= T0 >> (DATA_BITS + 1 - count);  
481 - T0 = res;  
482 - CC_SRC = (eflags & ~(CC_C | CC_O)) |  
483 - (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |  
484 - ((src >> (DATA_BITS - count)) & CC_C);  
485 - CC_OP = CC_OP_EFLAGS;  
486 - }  
487 - FORCE_RET();  
488 -}  
489 -  
490 -void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)  
491 -{  
492 - int count, res, eflags;  
493 - unsigned int src;  
494 -  
495 - count = T1 & 0x1f;  
496 -#if DATA_BITS == 16  
497 - count = rclw_table[count];  
498 -#elif DATA_BITS == 8  
499 - count = rclb_table[count];  
500 -#endif  
501 - if (count) {  
502 - eflags = cc_table[CC_OP].compute_all();  
503 - T0 &= DATA_MASK;  
504 - src = T0;  
505 - res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));  
506 - if (count > 1)  
507 - res |= T0 << (DATA_BITS + 1 - count);  
508 - T0 = res;  
509 - CC_SRC = (eflags & ~(CC_C | CC_O)) |  
510 - (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |  
511 - ((src >> (count - 1)) & CC_C);  
512 - CC_OP = CC_OP_EFLAGS;  
513 - }  
514 - FORCE_RET();  
515 -}  
516 -  
517 -void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)  
518 -{  
519 - int count;  
520 - count = T1 & 0x1f;  
521 - if (count) {  
522 - CC_SRC = (DATA_TYPE)T0 << (count - 1);  
523 - T0 = T0 << count;  
524 - CC_DST = T0;  
525 - CC_OP = CC_OP_SHLB + SHIFT;  
526 - }  
527 - FORCE_RET();  
528 -}  
529 -  
530 void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void) 409 void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
531 { 410 {
532 int count; 411 int count;
@@ -535,20 +414,6 @@ void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void) @@ -535,20 +414,6 @@ void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
535 FORCE_RET(); 414 FORCE_RET();
536 } 415 }
537 416
538 -void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)  
539 -{  
540 - int count;  
541 - count = T1 & 0x1f;  
542 - if (count) {  
543 - T0 &= DATA_MASK;  
544 - CC_SRC = T0 >> (count - 1);  
545 - T0 = T0 >> count;  
546 - CC_DST = T0;  
547 - CC_OP = CC_OP_SARB + SHIFT;  
548 - }  
549 - FORCE_RET();  
550 -}  
551 -  
552 void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void) 417 void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
553 { 418 {
554 int count; 419 int count;
@@ -558,20 +423,6 @@ void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void) @@ -558,20 +423,6 @@ void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
558 FORCE_RET(); 423 FORCE_RET();
559 } 424 }
560 425
561 -void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)  
562 -{  
563 - int count, src;  
564 - count = T1 & 0x1f;  
565 - if (count) {  
566 - src = (DATA_STYPE)T0;  
567 - CC_SRC = src >> (count - 1);  
568 - T0 = src >> count;  
569 - CC_DST = T0;  
570 - CC_OP = CC_OP_SARB + SHIFT;  
571 - }  
572 - FORCE_RET();  
573 -}  
574 -  
575 void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void) 426 void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
576 { 427 {
577 int count, src; 428 int count, src;
@@ -581,162 +432,11 @@ void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void) @@ -581,162 +432,11 @@ void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
581 FORCE_RET(); 432 FORCE_RET();
582 } 433 }
583 434
584 -#if DATA_BITS == 16  
585 -/* XXX: overflow flag might be incorrect in some cases in shldw */  
586 -void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)  
587 -{  
588 - int count;  
589 - unsigned int res;  
590 - count = PARAM1;  
591 - T1 &= 0xffff;  
592 - res = T1 | (T0 << 16);  
593 - CC_SRC = res >> (32 - count);  
594 - res <<= count;  
595 - if (count > 16)  
596 - res |= T1 << (count - 16);  
597 - T0 = res >> 16;  
598 - CC_DST = T0;  
599 -}  
600 -  
601 -void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)  
602 -{  
603 - int count;  
604 - unsigned int res;  
605 - count = ECX & 0x1f;  
606 - if (count) {  
607 - T1 &= 0xffff;  
608 - res = T1 | (T0 << 16);  
609 - CC_SRC = res >> (32 - count);  
610 - res <<= count;  
611 - if (count > 16)  
612 - res |= T1 << (count - 16);  
613 - T0 = res >> 16;  
614 - CC_DST = T0;  
615 - CC_OP = CC_OP_SARB + SHIFT;  
616 - }  
617 - FORCE_RET();  
618 -}  
619 -  
620 -void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)  
621 -{  
622 - int count;  
623 - unsigned int res;  
624 -  
625 - count = PARAM1;  
626 - res = (T0 & 0xffff) | (T1 << 16);  
627 - CC_SRC = res >> (count - 1);  
628 - res >>= count;  
629 - if (count > 16)  
630 - res |= T1 << (32 - count);  
631 - T0 = res;  
632 - CC_DST = T0;  
633 -}  
634 -  
635 -  
636 -void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)  
637 -{  
638 - int count;  
639 - unsigned int res;  
640 -  
641 - count = ECX & 0x1f;  
642 - if (count) {  
643 - res = (T0 & 0xffff) | (T1 << 16);  
644 - CC_SRC = res >> (count - 1);  
645 - res >>= count;  
646 - if (count > 16)  
647 - res |= T1 << (32 - count);  
648 - T0 = res;  
649 - CC_DST = T0;  
650 - CC_OP = CC_OP_SARB + SHIFT;  
651 - }  
652 - FORCE_RET();  
653 -}  
654 -#endif  
655 -  
656 -#if DATA_BITS == 32  
657 -void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)  
658 -{  
659 - int count;  
660 - count = PARAM1;  
661 - T0 &= DATA_MASK;  
662 - T1 &= DATA_MASK;  
663 - CC_SRC = T0 << (count - 1);  
664 - T0 = (T0 << count) | (T1 >> (DATA_BITS - count));  
665 - CC_DST = T0;  
666 -}  
667 -  
668 -void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)  
669 -{  
670 - int count;  
671 - count = ECX & 0x1f;  
672 - if (count) {  
673 - T0 &= DATA_MASK;  
674 - T1 &= DATA_MASK;  
675 - CC_SRC = T0 << (count - 1);  
676 - T0 = (T0 << count) | (T1 >> (DATA_BITS - count));  
677 - CC_DST = T0;  
678 - CC_OP = CC_OP_SHLB + SHIFT;  
679 - }  
680 - FORCE_RET();  
681 -}  
682 -  
683 -void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)  
684 -{  
685 - int count;  
686 - count = PARAM1;  
687 - T0 &= DATA_MASK;  
688 - T1 &= DATA_MASK;  
689 - CC_SRC = T0 >> (count - 1);  
690 - T0 = (T0 >> count) | (T1 << (DATA_BITS - count));  
691 - CC_DST = T0;  
692 -} 435 +#undef MEM_WRITE
  436 +#include "ops_template_mem.h"
693 437
694 -  
695 -void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)  
696 -{  
697 - int count;  
698 - count = ECX & 0x1f;  
699 - if (count) {  
700 - T0 &= DATA_MASK;  
701 - T1 &= DATA_MASK;  
702 - CC_SRC = T0 >> (count - 1);  
703 - T0 = (T0 >> count) | (T1 << (DATA_BITS - count));  
704 - CC_DST = T0;  
705 - CC_OP = CC_OP_SARB + SHIFT;  
706 - }  
707 - FORCE_RET();  
708 -}  
709 -#endif  
710 -  
711 -/* carry add/sub (we only need to set CC_OP differently) */  
712 -  
713 -void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)  
714 -{  
715 - int cf;  
716 - cf = cc_table[CC_OP].compute_c();  
717 - T0 = T0 + T1 + cf;  
718 - CC_OP = CC_OP_ADDB + SHIFT + cf * 3;  
719 -}  
720 -  
721 -void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)  
722 -{  
723 - int cf;  
724 - cf = cc_table[CC_OP].compute_c();  
725 - T0 = T0 - T1 - cf;  
726 - CC_OP = CC_OP_SUBB + SHIFT + cf * 3;  
727 -}  
728 -  
729 -void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void)  
730 -{  
731 - CC_SRC = T0;  
732 - CC_DST = EAX - T0;  
733 - if ((DATA_TYPE)CC_DST == 0) {  
734 - T0 = T1;  
735 - } else {  
736 - EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);  
737 - }  
738 - FORCE_RET();  
739 -} 438 +#define MEM_WRITE
  439 +#include "ops_template_mem.h"
740 440
741 /* bit operations */ 441 /* bit operations */
742 #if DATA_BITS >= 16 442 #if DATA_BITS >= 16
@@ -752,7 +452,7 @@ void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void) @@ -752,7 +452,7 @@ void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
752 { 452 {
753 int count; 453 int count;
754 count = T1 & SHIFT_MASK; 454 count = T1 & SHIFT_MASK;
755 - CC_SRC = T0 >> count; 455 + T1 = T0 >> count;
756 T0 |= (1 << count); 456 T0 |= (1 << count);
757 } 457 }
758 458
@@ -760,7 +460,7 @@ void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void) @@ -760,7 +460,7 @@ void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
760 { 460 {
761 int count; 461 int count;
762 count = T1 & SHIFT_MASK; 462 count = T1 & SHIFT_MASK;
763 - CC_SRC = T0 >> count; 463 + T1 = T0 >> count;
764 T0 &= ~(1 << count); 464 T0 &= ~(1 << count);
765 } 465 }
766 466
@@ -768,7 +468,7 @@ void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void) @@ -768,7 +468,7 @@ void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
768 { 468 {
769 int count; 469 int count;
770 count = T1 & SHIFT_MASK; 470 count = T1 & SHIFT_MASK;
771 - CC_SRC = T0 >> count; 471 + T1 = T0 >> count;
772 T0 ^= (1 << count); 472 T0 ^= (1 << count);
773 } 473 }
774 474
@@ -810,6 +510,13 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void) @@ -810,6 +510,13 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
810 510
811 #endif 511 #endif
812 512
  513 +#if DATA_BITS == 32
  514 +void OPPROTO op_update_bt_cc(void)
  515 +{
  516 + CC_SRC = T1;
  517 +}
  518 +#endif
  519 +
813 /* string operations */ 520 /* string operations */
814 /* XXX: maybe use lower level instructions to ease 16 bit / segment handling */ 521 /* XXX: maybe use lower level instructions to ease 16 bit / segment handling */
815 522
ops_template_mem.h 0 → 100644
  1 +/*
  2 + * i386 micro operations (included several times to generate
  3 + * different operand sizes)
  4 + *
  5 + * Copyright (c) 2003 Fabrice Bellard
  6 + *
  7 + * This library is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU Lesser General Public
  9 + * License as published by the Free Software Foundation; either
  10 + * version 2 of the License, or (at your option) any later version.
  11 + *
  12 + * This library is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this library; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 + */
  21 +#ifdef MEM_WRITE
  22 +
  23 +#if DATA_BITS == 8
  24 +#define MEM_SUFFIX b_mem
  25 +#elif DATA_BITS == 16
  26 +#define MEM_SUFFIX w_mem
  27 +#elif DATA_BITS == 32
  28 +#define MEM_SUFFIX l_mem
  29 +#endif
  30 +
  31 +#else
  32 +
  33 +#define MEM_SUFFIX SUFFIX
  34 +
  35 +#endif
  36 +
  37 +void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
  38 +{
  39 + int count, src;
  40 + count = T1 & SHIFT_MASK;
  41 + if (count) {
  42 + src = T0;
  43 + T0 &= DATA_MASK;
  44 + T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
  45 +#ifdef MEM_WRITE
  46 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  47 +#endif
  48 + CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
  49 + (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
  50 + (T0 & CC_C);
  51 + CC_OP = CC_OP_EFLAGS;
  52 + }
  53 + FORCE_RET();
  54 +}
  55 +
  56 +void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
  57 +{
  58 + int count, src;
  59 + count = T1 & SHIFT_MASK;
  60 + if (count) {
  61 + src = T0;
  62 + T0 &= DATA_MASK;
  63 + T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
  64 +#ifdef MEM_WRITE
  65 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  66 +#endif
  67 + CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
  68 + (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
  69 + ((T0 >> (DATA_BITS - 1)) & CC_C);
  70 + CC_OP = CC_OP_EFLAGS;
  71 + }
  72 + FORCE_RET();
  73 +}
  74 +
  75 +void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
  76 +{
  77 + int count;
  78 + count = T1 & SHIFT_MASK;
  79 + if (count) {
  80 + T0 &= DATA_MASK;
  81 + T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
  82 +#ifdef MEM_WRITE
  83 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  84 +#endif
  85 + }
  86 + FORCE_RET();
  87 +}
  88 +
  89 +void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
  90 +{
  91 + int count;
  92 + count = T1 & SHIFT_MASK;
  93 + if (count) {
  94 + T0 &= DATA_MASK;
  95 + T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
  96 +#ifdef MEM_WRITE
  97 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  98 +#endif
  99 + }
  100 + FORCE_RET();
  101 +}
  102 +
  103 +void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
  104 +{
  105 + int count, res, eflags;
  106 + unsigned int src;
  107 +
  108 + count = T1 & 0x1f;
  109 +#if DATA_BITS == 16
  110 + count = rclw_table[count];
  111 +#elif DATA_BITS == 8
  112 + count = rclb_table[count];
  113 +#endif
  114 + if (count) {
  115 + eflags = cc_table[CC_OP].compute_all();
  116 + T0 &= DATA_MASK;
  117 + src = T0;
  118 + res = (T0 << count) | ((eflags & CC_C) << (count - 1));
  119 + if (count > 1)
  120 + res |= T0 >> (DATA_BITS + 1 - count);
  121 + T0 = res;
  122 +#ifdef MEM_WRITE
  123 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  124 +#endif
  125 + CC_SRC = (eflags & ~(CC_C | CC_O)) |
  126 + (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
  127 + ((src >> (DATA_BITS - count)) & CC_C);
  128 + CC_OP = CC_OP_EFLAGS;
  129 + }
  130 + FORCE_RET();
  131 +}
  132 +
  133 +void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
  134 +{
  135 + int count, res, eflags;
  136 + unsigned int src;
  137 +
  138 + count = T1 & 0x1f;
  139 +#if DATA_BITS == 16
  140 + count = rclw_table[count];
  141 +#elif DATA_BITS == 8
  142 + count = rclb_table[count];
  143 +#endif
  144 + if (count) {
  145 + eflags = cc_table[CC_OP].compute_all();
  146 + T0 &= DATA_MASK;
  147 + src = T0;
  148 + res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
  149 + if (count > 1)
  150 + res |= T0 << (DATA_BITS + 1 - count);
  151 + T0 = res;
  152 +#ifdef MEM_WRITE
  153 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  154 +#endif
  155 + CC_SRC = (eflags & ~(CC_C | CC_O)) |
  156 + (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
  157 + ((src >> (count - 1)) & CC_C);
  158 + CC_OP = CC_OP_EFLAGS;
  159 + }
  160 + FORCE_RET();
  161 +}
  162 +
  163 +void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
  164 +{
  165 + int count, src;
  166 + count = T1 & 0x1f;
  167 + if (count) {
  168 + src = (DATA_TYPE)T0 << (count - 1);
  169 + T0 = T0 << count;
  170 +#ifdef MEM_WRITE
  171 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  172 +#endif
  173 + CC_SRC = src;
  174 + CC_DST = T0;
  175 + CC_OP = CC_OP_SHLB + SHIFT;
  176 + }
  177 + FORCE_RET();
  178 +}
  179 +
  180 +void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
  181 +{
  182 + int count, src;
  183 + count = T1 & 0x1f;
  184 + if (count) {
  185 + T0 &= DATA_MASK;
  186 + src = T0 >> (count - 1);
  187 + T0 = T0 >> count;
  188 +#ifdef MEM_WRITE
  189 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  190 +#endif
  191 + CC_SRC = src;
  192 + CC_DST = T0;
  193 + CC_OP = CC_OP_SARB + SHIFT;
  194 + }
  195 + FORCE_RET();
  196 +}
  197 +
  198 +void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
  199 +{
  200 + int count, src;
  201 + count = T1 & 0x1f;
  202 + if (count) {
  203 + src = (DATA_STYPE)T0;
  204 + T0 = src >> count;
  205 + src = src >> (count - 1);
  206 +#ifdef MEM_WRITE
  207 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  208 +#endif
  209 + CC_SRC = src;
  210 + CC_DST = T0;
  211 + CC_OP = CC_OP_SARB + SHIFT;
  212 + }
  213 + FORCE_RET();
  214 +}
  215 +
  216 +#if DATA_BITS == 16
  217 +/* XXX: overflow flag might be incorrect in some cases in shldw */
  218 +void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
  219 +{
  220 + int count;
  221 + unsigned int res, tmp;
  222 + count = PARAM1;
  223 + T1 &= 0xffff;
  224 + res = T1 | (T0 << 16);
  225 + tmp = res >> (32 - count);
  226 + res <<= count;
  227 + if (count > 16)
  228 + res |= T1 << (count - 16);
  229 + T0 = res >> 16;
  230 +#ifdef MEM_WRITE
  231 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  232 +#endif
  233 + CC_SRC = tmp;
  234 + CC_DST = T0;
  235 +}
  236 +
  237 +void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
  238 +{
  239 + int count;
  240 + unsigned int res, tmp;
  241 + count = ECX & 0x1f;
  242 + if (count) {
  243 + T1 &= 0xffff;
  244 + res = T1 | (T0 << 16);
  245 + tmp = res >> (32 - count);
  246 + res <<= count;
  247 + if (count > 16)
  248 + res |= T1 << (count - 16);
  249 + T0 = res >> 16;
  250 +#ifdef MEM_WRITE
  251 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  252 +#endif
  253 + CC_SRC = tmp;
  254 + CC_DST = T0;
  255 + CC_OP = CC_OP_SARB + SHIFT;
  256 + }
  257 + FORCE_RET();
  258 +}
  259 +
  260 +void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
  261 +{
  262 + int count;
  263 + unsigned int res, tmp;
  264 +
  265 + count = PARAM1;
  266 + res = (T0 & 0xffff) | (T1 << 16);
  267 + tmp = res >> (count - 1);
  268 + res >>= count;
  269 + if (count > 16)
  270 + res |= T1 << (32 - count);
  271 + T0 = res;
  272 +#ifdef MEM_WRITE
  273 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  274 +#endif
  275 + CC_SRC = tmp;
  276 + CC_DST = T0;
  277 +}
  278 +
  279 +
  280 +void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
  281 +{
  282 + int count;
  283 + unsigned int res, tmp;
  284 +
  285 + count = ECX & 0x1f;
  286 + if (count) {
  287 + res = (T0 & 0xffff) | (T1 << 16);
  288 + tmp = res >> (count - 1);
  289 + res >>= count;
  290 + if (count > 16)
  291 + res |= T1 << (32 - count);
  292 + T0 = res;
  293 +#ifdef MEM_WRITE
  294 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  295 +#endif
  296 + CC_SRC = tmp;
  297 + CC_DST = T0;
  298 + CC_OP = CC_OP_SARB + SHIFT;
  299 + }
  300 + FORCE_RET();
  301 +}
  302 +#endif
  303 +
  304 +#if DATA_BITS == 32
  305 +void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
  306 +{
  307 + int count, tmp;
  308 + count = PARAM1;
  309 + T0 &= DATA_MASK;
  310 + T1 &= DATA_MASK;
  311 + tmp = T0 << (count - 1);
  312 + T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
  313 +#ifdef MEM_WRITE
  314 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  315 +#endif
  316 + CC_SRC = tmp;
  317 + CC_DST = T0;
  318 +}
  319 +
  320 +void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
  321 +{
  322 + int count, tmp;
  323 + count = ECX & 0x1f;
  324 + if (count) {
  325 + T0 &= DATA_MASK;
  326 + T1 &= DATA_MASK;
  327 + tmp = T0 << (count - 1);
  328 + T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
  329 +#ifdef MEM_WRITE
  330 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  331 +#endif
  332 + CC_SRC = tmp;
  333 + CC_DST = T0;
  334 + CC_OP = CC_OP_SHLB + SHIFT;
  335 + }
  336 + FORCE_RET();
  337 +}
  338 +
  339 +void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
  340 +{
  341 + int count, tmp;
  342 + count = PARAM1;
  343 + T0 &= DATA_MASK;
  344 + T1 &= DATA_MASK;
  345 + tmp = T0 >> (count - 1);
  346 + T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
  347 +#ifdef MEM_WRITE
  348 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  349 +#endif
  350 + CC_SRC = tmp;
  351 + CC_DST = T0;
  352 +}
  353 +
  354 +
  355 +void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
  356 +{
  357 + int count, tmp;
  358 + count = ECX & 0x1f;
  359 + if (count) {
  360 + T0 &= DATA_MASK;
  361 + T1 &= DATA_MASK;
  362 + tmp = T0 >> (count - 1);
  363 + T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
  364 +#ifdef MEM_WRITE
  365 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  366 +#endif
  367 + CC_SRC = tmp;
  368 + CC_DST = T0;
  369 + CC_OP = CC_OP_SARB + SHIFT;
  370 + }
  371 + FORCE_RET();
  372 +}
  373 +#endif
  374 +
  375 +/* carry add/sub (we only need to set CC_OP differently) */
  376 +
  377 +void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
  378 +{
  379 + int cf;
  380 + cf = cc_table[CC_OP].compute_c();
  381 + T0 = T0 + T1 + cf;
  382 +#ifdef MEM_WRITE
  383 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  384 +#endif
  385 + CC_SRC = T1;
  386 + CC_DST = T0;
  387 + CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
  388 +}
  389 +
  390 +void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
  391 +{
  392 + int cf;
  393 + cf = cc_table[CC_OP].compute_c();
  394 + T0 = T0 - T1 - cf;
  395 +#ifdef MEM_WRITE
  396 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  397 +#endif
  398 + CC_SRC = T1;
  399 + CC_DST = T0;
  400 + CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
  401 +}
  402 +
  403 +void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
  404 +{
  405 + unsigned int src, dst;
  406 +
  407 + src = T0;
  408 + dst = EAX - T0;
  409 + if ((DATA_TYPE)dst == 0) {
  410 + T0 = T1;
  411 + } else {
  412 + EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
  413 + }
  414 +#ifdef MEM_WRITE
  415 + glue(st, SUFFIX)((uint8_t *)A0, T0);
  416 +#endif
  417 + CC_SRC = src;
  418 + CC_DST = dst;
  419 + FORCE_RET();
  420 +}
  421 +
  422 +#undef MEM_SUFFIX
  423 +#undef MEM_WRITE
translate-i386.c
@@ -390,6 +390,21 @@ static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = { @@ -390,6 +390,21 @@ static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
390 }, 390 },
391 }; 391 };
392 392
  393 +static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3][2] = {
  394 + [OT_BYTE] = {
  395 + gen_op_adcb_mem_T0_T1_cc,
  396 + gen_op_sbbb_mem_T0_T1_cc,
  397 + },
  398 + [OT_WORD] = {
  399 + gen_op_adcw_mem_T0_T1_cc,
  400 + gen_op_sbbw_mem_T0_T1_cc,
  401 + },
  402 + [OT_LONG] = {
  403 + gen_op_adcl_mem_T0_T1_cc,
  404 + gen_op_sbbl_mem_T0_T1_cc,
  405 + },
  406 +};
  407 +
393 static const int cc_op_arithb[8] = { 408 static const int cc_op_arithb[8] = {
394 CC_OP_ADDB, 409 CC_OP_ADDB,
395 CC_OP_LOGICB, 410 CC_OP_LOGICB,
@@ -407,6 +422,12 @@ static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = { @@ -407,6 +422,12 @@ static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = {
407 gen_op_cmpxchgl_T0_T1_EAX_cc, 422 gen_op_cmpxchgl_T0_T1_EAX_cc,
408 }; 423 };
409 424
  425 +static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3] = {
  426 + gen_op_cmpxchgb_mem_T0_T1_EAX_cc,
  427 + gen_op_cmpxchgw_mem_T0_T1_EAX_cc,
  428 + gen_op_cmpxchgl_mem_T0_T1_EAX_cc,
  429 +};
  430 +
410 static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = { 431 static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
411 [OT_BYTE] = { 432 [OT_BYTE] = {
412 gen_op_rolb_T0_T1_cc, 433 gen_op_rolb_T0_T1_cc,
@@ -440,6 +461,39 @@ static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = { @@ -440,6 +461,39 @@ static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
440 }, 461 },
441 }; 462 };
442 463
  464 +static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3][8] = {
  465 + [OT_BYTE] = {
  466 + gen_op_rolb_mem_T0_T1_cc,
  467 + gen_op_rorb_mem_T0_T1_cc,
  468 + gen_op_rclb_mem_T0_T1_cc,
  469 + gen_op_rcrb_mem_T0_T1_cc,
  470 + gen_op_shlb_mem_T0_T1_cc,
  471 + gen_op_shrb_mem_T0_T1_cc,
  472 + gen_op_shlb_mem_T0_T1_cc,
  473 + gen_op_sarb_mem_T0_T1_cc,
  474 + },
  475 + [OT_WORD] = {
  476 + gen_op_rolw_mem_T0_T1_cc,
  477 + gen_op_rorw_mem_T0_T1_cc,
  478 + gen_op_rclw_mem_T0_T1_cc,
  479 + gen_op_rcrw_mem_T0_T1_cc,
  480 + gen_op_shlw_mem_T0_T1_cc,
  481 + gen_op_shrw_mem_T0_T1_cc,
  482 + gen_op_shlw_mem_T0_T1_cc,
  483 + gen_op_sarw_mem_T0_T1_cc,
  484 + },
  485 + [OT_LONG] = {
  486 + gen_op_roll_mem_T0_T1_cc,
  487 + gen_op_rorl_mem_T0_T1_cc,
  488 + gen_op_rcll_mem_T0_T1_cc,
  489 + gen_op_rcrl_mem_T0_T1_cc,
  490 + gen_op_shll_mem_T0_T1_cc,
  491 + gen_op_shrl_mem_T0_T1_cc,
  492 + gen_op_shll_mem_T0_T1_cc,
  493 + gen_op_sarl_mem_T0_T1_cc,
  494 + },
  495 +};
  496 +
443 static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = { 497 static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = {
444 [0] = { 498 [0] = {
445 gen_op_shldw_T0_T1_im_cc, 499 gen_op_shldw_T0_T1_im_cc,
@@ -462,6 +516,28 @@ static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = { @@ -462,6 +516,28 @@ static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = {
462 }, 516 },
463 }; 517 };
464 518
  519 +static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[2][2] = {
  520 + [0] = {
  521 + gen_op_shldw_mem_T0_T1_im_cc,
  522 + gen_op_shrdw_mem_T0_T1_im_cc,
  523 + },
  524 + [1] = {
  525 + gen_op_shldl_mem_T0_T1_im_cc,
  526 + gen_op_shrdl_mem_T0_T1_im_cc,
  527 + },
  528 +};
  529 +
  530 +static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[2][2] = {
  531 + [0] = {
  532 + gen_op_shldw_mem_T0_T1_ECX_cc,
  533 + gen_op_shrdw_mem_T0_T1_ECX_cc,
  534 + },
  535 + [1] = {
  536 + gen_op_shldl_mem_T0_T1_ECX_cc,
  537 + gen_op_shrdl_mem_T0_T1_ECX_cc,
  538 + },
  539 +};
  540 +
465 static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = { 541 static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
466 [0] = { 542 [0] = {
467 gen_op_btw_T0_T1_cc, 543 gen_op_btw_T0_T1_cc,
@@ -763,11 +839,14 @@ static void gen_op(DisasContext *s1, int op, int ot, int d) @@ -763,11 +839,14 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
763 case OP_SBBL: 839 case OP_SBBL:
764 if (s1->cc_op != CC_OP_DYNAMIC) 840 if (s1->cc_op != CC_OP_DYNAMIC)
765 gen_op_set_cc_op(s1->cc_op); 841 gen_op_set_cc_op(s1->cc_op);
766 - gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL](); 842 + if (d != OR_TMP0) {
  843 + gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
  844 + gen_op_mov_reg_T0[ot][d]();
  845 + } else {
  846 + gen_op_arithc_mem_T0_T1_cc[ot][op - OP_ADCL]();
  847 + }
767 s1->cc_op = CC_OP_DYNAMIC; 848 s1->cc_op = CC_OP_DYNAMIC;
768 - /* XXX: incorrect: CC_OP must also be modified AFTER memory access */  
769 - gen_update_cc = gen_op_update2_cc;  
770 - break; 849 + goto the_end;
771 case OP_ADDL: 850 case OP_ADDL:
772 gen_op_addl_T0_T1(); 851 gen_op_addl_T0_T1();
773 s1->cc_op = CC_OP_ADDB + ot; 852 s1->cc_op = CC_OP_ADDB + ot;
@@ -802,6 +881,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d) @@ -802,6 +881,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
802 exception support) */ 881 exception support) */
803 if (gen_update_cc) 882 if (gen_update_cc)
804 gen_update_cc(); 883 gen_update_cc();
  884 + the_end: ;
805 } 885 }
806 886
807 /* if d == OR_TMP0, it means memory operand (address in A0) */ 887 /* if d == OR_TMP0, it means memory operand (address in A0) */
@@ -831,14 +911,18 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) @@ -831,14 +911,18 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
831 { 911 {
832 if (d != OR_TMP0) 912 if (d != OR_TMP0)
833 gen_op_mov_TN_reg[ot][0][d](); 913 gen_op_mov_TN_reg[ot][0][d]();
  914 + else
  915 + gen_op_ld_T0_A0[ot]();
834 if (s != OR_TMP1) 916 if (s != OR_TMP1)
835 gen_op_mov_TN_reg[ot][1][s](); 917 gen_op_mov_TN_reg[ot][1][s]();
836 /* for zero counts, flags are not updated, so must do it dynamically */ 918 /* for zero counts, flags are not updated, so must do it dynamically */
837 if (s1->cc_op != CC_OP_DYNAMIC) 919 if (s1->cc_op != CC_OP_DYNAMIC)
838 gen_op_set_cc_op(s1->cc_op); 920 gen_op_set_cc_op(s1->cc_op);
839 -  
840 - gen_op_shift_T0_T1_cc[ot][op]();  
841 - 921 +
  922 + if (d != OR_TMP0)
  923 + gen_op_shift_T0_T1_cc[ot][op]();
  924 + else
  925 + gen_op_shift_mem_T0_T1_cc[ot][op]();
842 if (d != OR_TMP0) 926 if (d != OR_TMP0)
843 gen_op_mov_reg_T0[ot][d](); 927 gen_op_mov_reg_T0[ot][d]();
844 s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ 928 s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
@@ -1885,8 +1969,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1885,8 +1969,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1885 } else { 1969 } else {
1886 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1970 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1887 gen_op_ld_T0_A0[ot](); 1971 gen_op_ld_T0_A0[ot]();
1888 - gen_op_cmpxchg_T0_T1_EAX_cc[ot]();  
1889 - gen_op_st_T0_A0[ot](); 1972 + gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot]();
1890 } 1973 }
1891 s->cc_op = CC_OP_SUBB + ot; 1974 s->cc_op = CC_OP_SUBB + ot;
1892 break; 1975 break;
@@ -2264,7 +2347,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2264,7 +2347,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2264 2347
2265 if (mod != 3) { 2348 if (mod != 3) {
2266 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 2349 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2267 - gen_op_ld_T0_A0[ot]();  
2268 opreg = OR_TMP0; 2350 opreg = OR_TMP0;
2269 } else { 2351 } else {
2270 opreg = rm + OR_EAX; 2352 opreg = rm + OR_EAX;
@@ -2279,10 +2361,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2279,10 +2361,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2279 } 2361 }
2280 gen_shifti(s, op, ot, opreg, shift); 2362 gen_shifti(s, op, ot, opreg, shift);
2281 } 2363 }
2282 -  
2283 - if (mod != 3) {  
2284 - gen_op_st_T0_A0[ot]();  
2285 - }  
2286 } 2364 }
2287 break; 2365 break;
2288 case 0xd0: 2366 case 0xd0:
@@ -2330,7 +2408,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2330,7 +2408,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2330 val = ldub(s->pc++); 2408 val = ldub(s->pc++);
2331 val &= 0x1f; 2409 val &= 0x1f;
2332 if (val) { 2410 if (val) {
2333 - gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val); 2411 + if (mod == 3)
  2412 + gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
  2413 + else
  2414 + gen_op_shiftd_mem_T0_T1_im_cc[ot - OT_WORD][op](val);
2334 if (op == 0 && ot != OT_WORD) 2415 if (op == 0 && ot != OT_WORD)
2335 s->cc_op = CC_OP_SHLB + ot; 2416 s->cc_op = CC_OP_SHLB + ot;
2336 else 2417 else
@@ -2339,12 +2420,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2339,12 +2420,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2339 } else { 2420 } else {
2340 if (s->cc_op != CC_OP_DYNAMIC) 2421 if (s->cc_op != CC_OP_DYNAMIC)
2341 gen_op_set_cc_op(s->cc_op); 2422 gen_op_set_cc_op(s->cc_op);
2342 - gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op](); 2423 + if (mod == 3)
  2424 + gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
  2425 + else
  2426 + gen_op_shiftd_mem_T0_T1_ECX_cc[ot - OT_WORD][op]();
2343 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ 2427 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2344 } 2428 }
2345 - if (mod != 3) {  
2346 - gen_op_st_T0_A0[ot]();  
2347 - } else { 2429 + if (mod == 3) {
2348 gen_op_mov_reg_T0[ot][rm](); 2430 gen_op_mov_reg_T0[ot][rm]();
2349 } 2431 }
2350 break; 2432 break;
@@ -3202,6 +3284,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3202,6 +3284,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3202 gen_op_st_T0_A0[ot](); 3284 gen_op_st_T0_A0[ot]();
3203 else 3285 else
3204 gen_op_mov_reg_T0[ot][rm](); 3286 gen_op_mov_reg_T0[ot][rm]();
  3287 + gen_op_update_bt_cc();
3205 } 3288 }
3206 break; 3289 break;
3207 case 0x1a3: /* bt Gv, Ev */ 3290 case 0x1a3: /* bt Gv, Ev */
@@ -3240,6 +3323,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3240,6 +3323,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3240 gen_op_st_T0_A0[ot](); 3323 gen_op_st_T0_A0[ot]();
3241 else 3324 else
3242 gen_op_mov_reg_T0[ot][rm](); 3325 gen_op_mov_reg_T0[ot][rm]();
  3326 + gen_op_update_bt_cc();
3243 } 3327 }
3244 break; 3328 break;
3245 case 0x1bc: /* bsf */ 3329 case 0x1bc: /* bsf */
@@ -3640,6 +3724,13 @@ static uint16_t opc_read_flags[NB_OPS] = { @@ -3640,6 +3724,13 @@ static uint16_t opc_read_flags[NB_OPS] = {
3640 [INDEX_op_sbbw_T0_T1_cc] = CC_C, 3724 [INDEX_op_sbbw_T0_T1_cc] = CC_C,
3641 [INDEX_op_sbbl_T0_T1_cc] = CC_C, 3725 [INDEX_op_sbbl_T0_T1_cc] = CC_C,
3642 3726
  3727 + [INDEX_op_adcb_mem_T0_T1_cc] = CC_C,
  3728 + [INDEX_op_adcw_mem_T0_T1_cc] = CC_C,
  3729 + [INDEX_op_adcl_mem_T0_T1_cc] = CC_C,
  3730 + [INDEX_op_sbbb_mem_T0_T1_cc] = CC_C,
  3731 + [INDEX_op_sbbw_mem_T0_T1_cc] = CC_C,
  3732 + [INDEX_op_sbbl_mem_T0_T1_cc] = CC_C,
  3733 +
3643 /* subtle: due to the incl/decl implementation, C is used */ 3734 /* subtle: due to the incl/decl implementation, C is used */
3644 [INDEX_op_update_inc_cc] = CC_C, 3735 [INDEX_op_update_inc_cc] = CC_C,
3645 3736
@@ -3717,23 +3808,38 @@ static uint16_t opc_read_flags[NB_OPS] = { @@ -3717,23 +3808,38 @@ static uint16_t opc_read_flags[NB_OPS] = {
3717 [INDEX_op_rcrb_T0_T1_cc] = CC_C, 3808 [INDEX_op_rcrb_T0_T1_cc] = CC_C,
3718 [INDEX_op_rcrw_T0_T1_cc] = CC_C, 3809 [INDEX_op_rcrw_T0_T1_cc] = CC_C,
3719 [INDEX_op_rcrl_T0_T1_cc] = CC_C, 3810 [INDEX_op_rcrl_T0_T1_cc] = CC_C,
  3811 +
  3812 + [INDEX_op_rclb_mem_T0_T1_cc] = CC_C,
  3813 + [INDEX_op_rclw_mem_T0_T1_cc] = CC_C,
  3814 + [INDEX_op_rcll_mem_T0_T1_cc] = CC_C,
  3815 + [INDEX_op_rcrb_mem_T0_T1_cc] = CC_C,
  3816 + [INDEX_op_rcrw_mem_T0_T1_cc] = CC_C,
  3817 + [INDEX_op_rcrl_mem_T0_T1_cc] = CC_C,
3720 }; 3818 };
3721 3819
3722 /* flags written by an operation */ 3820 /* flags written by an operation */
3723 static uint16_t opc_write_flags[NB_OPS] = { 3821 static uint16_t opc_write_flags[NB_OPS] = {
3724 [INDEX_op_update2_cc] = CC_OSZAPC, 3822 [INDEX_op_update2_cc] = CC_OSZAPC,
3725 [INDEX_op_update1_cc] = CC_OSZAPC, 3823 [INDEX_op_update1_cc] = CC_OSZAPC,
  3824 + [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
  3825 + [INDEX_op_update_neg_cc] = CC_OSZAPC,
  3826 + /* subtle: due to the incl/decl implementation, C is used */
  3827 + [INDEX_op_update_inc_cc] = CC_OSZAPC,
  3828 + [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
  3829 +
3726 [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC, 3830 [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
3727 [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC, 3831 [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
3728 [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC, 3832 [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
3729 [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC, 3833 [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
3730 [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC, 3834 [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
3731 [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC, 3835 [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,
3732 - [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,  
3733 - [INDEX_op_update_neg_cc] = CC_OSZAPC,  
3734 - /* subtle: due to the incl/decl implementation, C is used */  
3735 - [INDEX_op_update_inc_cc] = CC_OSZAPC,  
3736 - [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC, 3836 +
  3837 + [INDEX_op_adcb_mem_T0_T1_cc] = CC_OSZAPC,
  3838 + [INDEX_op_adcw_mem_T0_T1_cc] = CC_OSZAPC,
  3839 + [INDEX_op_adcl_mem_T0_T1_cc] = CC_OSZAPC,
  3840 + [INDEX_op_sbbb_mem_T0_T1_cc] = CC_OSZAPC,
  3841 + [INDEX_op_sbbw_mem_T0_T1_cc] = CC_OSZAPC,
  3842 + [INDEX_op_sbbl_mem_T0_T1_cc] = CC_OSZAPC,
3737 3843
3738 [INDEX_op_mulb_AL_T0] = CC_OSZAPC, 3844 [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
3739 [INDEX_op_imulb_AL_T0] = CC_OSZAPC, 3845 [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
@@ -3795,6 +3901,42 @@ static uint16_t opc_write_flags[NB_OPS] = { @@ -3795,6 +3901,42 @@ static uint16_t opc_write_flags[NB_OPS] = {
3795 [INDEX_op_shrdw_T0_T1_im_cc] = CC_OSZAPC, 3901 [INDEX_op_shrdw_T0_T1_im_cc] = CC_OSZAPC,
3796 [INDEX_op_shrdl_T0_T1_im_cc] = CC_OSZAPC, 3902 [INDEX_op_shrdl_T0_T1_im_cc] = CC_OSZAPC,
3797 3903
  3904 + [INDEX_op_rolb_mem_T0_T1_cc] = CC_O | CC_C,
  3905 + [INDEX_op_rolw_mem_T0_T1_cc] = CC_O | CC_C,
  3906 + [INDEX_op_roll_mem_T0_T1_cc] = CC_O | CC_C,
  3907 + [INDEX_op_rorb_mem_T0_T1_cc] = CC_O | CC_C,
  3908 + [INDEX_op_rorw_mem_T0_T1_cc] = CC_O | CC_C,
  3909 + [INDEX_op_rorl_mem_T0_T1_cc] = CC_O | CC_C,
  3910 +
  3911 + [INDEX_op_rclb_mem_T0_T1_cc] = CC_O | CC_C,
  3912 + [INDEX_op_rclw_mem_T0_T1_cc] = CC_O | CC_C,
  3913 + [INDEX_op_rcll_mem_T0_T1_cc] = CC_O | CC_C,
  3914 + [INDEX_op_rcrb_mem_T0_T1_cc] = CC_O | CC_C,
  3915 + [INDEX_op_rcrw_mem_T0_T1_cc] = CC_O | CC_C,
  3916 + [INDEX_op_rcrl_mem_T0_T1_cc] = CC_O | CC_C,
  3917 +
  3918 + [INDEX_op_shlb_mem_T0_T1_cc] = CC_OSZAPC,
  3919 + [INDEX_op_shlw_mem_T0_T1_cc] = CC_OSZAPC,
  3920 + [INDEX_op_shll_mem_T0_T1_cc] = CC_OSZAPC,
  3921 +
  3922 + [INDEX_op_shrb_mem_T0_T1_cc] = CC_OSZAPC,
  3923 + [INDEX_op_shrw_mem_T0_T1_cc] = CC_OSZAPC,
  3924 + [INDEX_op_shrl_mem_T0_T1_cc] = CC_OSZAPC,
  3925 +
  3926 + [INDEX_op_sarb_mem_T0_T1_cc] = CC_OSZAPC,
  3927 + [INDEX_op_sarw_mem_T0_T1_cc] = CC_OSZAPC,
  3928 + [INDEX_op_sarl_mem_T0_T1_cc] = CC_OSZAPC,
  3929 +
  3930 + [INDEX_op_shldw_mem_T0_T1_ECX_cc] = CC_OSZAPC,
  3931 + [INDEX_op_shldl_mem_T0_T1_ECX_cc] = CC_OSZAPC,
  3932 + [INDEX_op_shldw_mem_T0_T1_im_cc] = CC_OSZAPC,
  3933 + [INDEX_op_shldl_mem_T0_T1_im_cc] = CC_OSZAPC,
  3934 +
  3935 + [INDEX_op_shrdw_mem_T0_T1_ECX_cc] = CC_OSZAPC,
  3936 + [INDEX_op_shrdl_mem_T0_T1_ECX_cc] = CC_OSZAPC,
  3937 + [INDEX_op_shrdw_mem_T0_T1_im_cc] = CC_OSZAPC,
  3938 + [INDEX_op_shrdl_mem_T0_T1_im_cc] = CC_OSZAPC,
  3939 +
3798 [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC, 3940 [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
3799 [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC, 3941 [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
3800 [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC, 3942 [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
@@ -3832,6 +3974,10 @@ static uint16_t opc_write_flags[NB_OPS] = { @@ -3832,6 +3974,10 @@ static uint16_t opc_write_flags[NB_OPS] = {
3832 [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC, 3974 [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
3833 [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC, 3975 [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
3834 3976
  3977 + [INDEX_op_cmpxchgb_mem_T0_T1_EAX_cc] = CC_OSZAPC,
  3978 + [INDEX_op_cmpxchgw_mem_T0_T1_EAX_cc] = CC_OSZAPC,
  3979 + [INDEX_op_cmpxchgl_mem_T0_T1_EAX_cc] = CC_OSZAPC,
  3980 +
3835 [INDEX_op_cmpxchg8b] = CC_Z, 3981 [INDEX_op_cmpxchg8b] = CC_Z,
3836 [INDEX_op_lar] = CC_Z, 3982 [INDEX_op_lar] = CC_Z,
3837 [INDEX_op_lsl] = CC_Z, 3983 [INDEX_op_lsl] = CC_Z,
@@ -3844,8 +3990,10 @@ static uint16_t opc_simpler[NB_OPS] = { @@ -3844,8 +3990,10 @@ static uint16_t opc_simpler[NB_OPS] = {
3844 [INDEX_op_update2_cc] = INDEX_op_nop, 3990 [INDEX_op_update2_cc] = INDEX_op_nop,
3845 [INDEX_op_update1_cc] = INDEX_op_nop, 3991 [INDEX_op_update1_cc] = INDEX_op_nop,
3846 [INDEX_op_update_neg_cc] = INDEX_op_nop, 3992 [INDEX_op_update_neg_cc] = INDEX_op_nop,
  3993 +#if 0
  3994 + /* broken: CC_OP logic must be rewritten */
3847 [INDEX_op_update_inc_cc] = INDEX_op_nop, 3995 [INDEX_op_update_inc_cc] = INDEX_op_nop,
3848 - 3996 +#endif
3849 [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1, 3997 [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
3850 [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1, 3998 [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,
3851 [INDEX_op_roll_T0_T1_cc] = INDEX_op_roll_T0_T1, 3999 [INDEX_op_roll_T0_T1_cc] = INDEX_op_roll_T0_T1,
@@ -3854,6 +4002,14 @@ static uint16_t opc_simpler[NB_OPS] = { @@ -3854,6 +4002,14 @@ static uint16_t opc_simpler[NB_OPS] = {
3854 [INDEX_op_rorw_T0_T1_cc] = INDEX_op_rorw_T0_T1, 4002 [INDEX_op_rorw_T0_T1_cc] = INDEX_op_rorw_T0_T1,
3855 [INDEX_op_rorl_T0_T1_cc] = INDEX_op_rorl_T0_T1, 4003 [INDEX_op_rorl_T0_T1_cc] = INDEX_op_rorl_T0_T1,
3856 4004
  4005 + [INDEX_op_rolb_mem_T0_T1_cc] = INDEX_op_rolb_mem_T0_T1,
  4006 + [INDEX_op_rolw_mem_T0_T1_cc] = INDEX_op_rolw_mem_T0_T1,
  4007 + [INDEX_op_roll_mem_T0_T1_cc] = INDEX_op_roll_mem_T0_T1,
  4008 +
  4009 + [INDEX_op_rorb_mem_T0_T1_cc] = INDEX_op_rorb_mem_T0_T1,
  4010 + [INDEX_op_rorw_mem_T0_T1_cc] = INDEX_op_rorw_mem_T0_T1,
  4011 + [INDEX_op_rorl_mem_T0_T1_cc] = INDEX_op_rorl_mem_T0_T1,
  4012 +
3857 [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1, 4013 [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
3858 [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1, 4014 [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
3859 [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1, 4015 [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
@@ -3971,6 +4127,10 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc @@ -3971,6 +4127,10 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc
3971 break; 4127 break;
3972 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && 4128 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
3973 (pc_ptr - pc_start) < (TARGET_PAGE_SIZE - 32)); 4129 (pc_ptr - pc_start) < (TARGET_PAGE_SIZE - 32));
  4130 + if (!dc->tf && dc->is_jmp == DISAS_NEXT) {
  4131 + gen_jmp(dc, ret - (unsigned long)dc->cs_base);
  4132 + }
  4133 +
3974 /* we must store the eflags state if it is not already done */ 4134 /* we must store the eflags state if it is not already done */
3975 if (dc->is_jmp != DISAS_TB_JUMP) { 4135 if (dc->is_jmp != DISAS_TB_JUMP) {
3976 if (dc->cc_op != CC_OP_DYNAMIC) 4136 if (dc->cc_op != CC_OP_DYNAMIC)
@@ -3983,12 +4143,19 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc @@ -3983,12 +4143,19 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc
3983 if (dc->tf) { 4143 if (dc->tf) {
3984 gen_op_raise_exception(EXCP01_SSTP); 4144 gen_op_raise_exception(EXCP01_SSTP);
3985 } 4145 }
3986 - if (dc->is_jmp != 3) { 4146 + if (dc->is_jmp != DISAS_TB_JUMP) {
3987 /* indicate that the hash table must be used to find the next TB */ 4147 /* indicate that the hash table must be used to find the next TB */
3988 gen_op_movl_T0_0(); 4148 gen_op_movl_T0_0();
3989 } 4149 }
3990 *gen_opc_ptr = INDEX_op_end; 4150 *gen_opc_ptr = INDEX_op_end;
3991 - 4151 + /* we don't forget to fill the last values */
  4152 + if (search_pc) {
  4153 + j = gen_opc_ptr - gen_opc_buf;
  4154 + lj++;
  4155 + while (lj <= j)
  4156 + gen_opc_instr_start[lj++] = 0;
  4157 + }
  4158 +
3992 #ifdef DEBUG_DISAS 4159 #ifdef DEBUG_DISAS
3993 if (loglevel) { 4160 if (loglevel) {
3994 fprintf(logfile, "----------------\n"); 4161 fprintf(logfile, "----------------\n");