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 174 helper-$(TARGET_ARCH).o: helper-$(TARGET_ARCH).c
175 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 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 1200 }
1201 1201  
1202 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 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 1208 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
1209 1209 const char *name, *p;
1210 1210 name = strtab + sym->st_name;
... ...
ops_template.h
... ... @@ -406,127 +406,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
406 406  
407 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 409 void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
531 410 {
532 411 int count;
... ... @@ -535,20 +414,6 @@ void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
535 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 417 void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
553 418 {
554 419 int count;
... ... @@ -558,20 +423,6 @@ void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
558 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 426 void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
576 427 {
577 428 int count, src;
... ... @@ -581,162 +432,11 @@ void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
581 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 441 /* bit operations */
742 442 #if DATA_BITS >= 16
... ... @@ -752,7 +452,7 @@ void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
752 452 {
753 453 int count;
754 454 count = T1 & SHIFT_MASK;
755   - CC_SRC = T0 >> count;
  455 + T1 = T0 >> count;
756 456 T0 |= (1 << count);
757 457 }
758 458  
... ... @@ -760,7 +460,7 @@ void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
760 460 {
761 461 int count;
762 462 count = T1 & SHIFT_MASK;
763   - CC_SRC = T0 >> count;
  463 + T1 = T0 >> count;
764 464 T0 &= ~(1 << count);
765 465 }
766 466  
... ... @@ -768,7 +468,7 @@ void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
768 468 {
769 469 int count;
770 470 count = T1 & SHIFT_MASK;
771   - CC_SRC = T0 >> count;
  471 + T1 = T0 >> count;
772 472 T0 ^= (1 << count);
773 473 }
774 474  
... ... @@ -810,6 +510,13 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
810 510  
811 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 520 /* string operations */
814 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 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 408 static const int cc_op_arithb[8] = {
394 409 CC_OP_ADDB,
395 410 CC_OP_LOGICB,
... ... @@ -407,6 +422,12 @@ static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = {
407 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 431 static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
411 432 [OT_BYTE] = {
412 433 gen_op_rolb_T0_T1_cc,
... ... @@ -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 497 static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = {
444 498 [0] = {
445 499 gen_op_shldw_T0_T1_im_cc,
... ... @@ -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 541 static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
466 542 [0] = {
467 543 gen_op_btw_T0_T1_cc,
... ... @@ -763,11 +839,14 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
763 839 case OP_SBBL:
764 840 if (s1->cc_op != CC_OP_DYNAMIC)
765 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 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 850 case OP_ADDL:
772 851 gen_op_addl_T0_T1();
773 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 881 exception support) */
803 882 if (gen_update_cc)
804 883 gen_update_cc();
  884 + the_end: ;
805 885 }
806 886  
807 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 911 {
832 912 if (d != OR_TMP0)
833 913 gen_op_mov_TN_reg[ot][0][d]();
  914 + else
  915 + gen_op_ld_T0_A0[ot]();
834 916 if (s != OR_TMP1)
835 917 gen_op_mov_TN_reg[ot][1][s]();
836 918 /* for zero counts, flags are not updated, so must do it dynamically */
837 919 if (s1->cc_op != CC_OP_DYNAMIC)
838 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 926 if (d != OR_TMP0)
843 927 gen_op_mov_reg_T0[ot][d]();
844 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 1969 } else {
1886 1970 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1887 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 1974 s->cc_op = CC_OP_SUBB + ot;
1892 1975 break;
... ... @@ -2264,7 +2347,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2264 2347  
2265 2348 if (mod != 3) {
2266 2349 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2267   - gen_op_ld_T0_A0[ot]();
2268 2350 opreg = OR_TMP0;
2269 2351 } else {
2270 2352 opreg = rm + OR_EAX;
... ... @@ -2279,10 +2361,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2279 2361 }
2280 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 2365 break;
2288 2366 case 0xd0:
... ... @@ -2330,7 +2408,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2330 2408 val = ldub(s->pc++);
2331 2409 val &= 0x1f;
2332 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 2415 if (op == 0 && ot != OT_WORD)
2335 2416 s->cc_op = CC_OP_SHLB + ot;
2336 2417 else
... ... @@ -2339,12 +2420,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2339 2420 } else {
2340 2421 if (s->cc_op != CC_OP_DYNAMIC)
2341 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 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 2430 gen_op_mov_reg_T0[ot][rm]();
2349 2431 }
2350 2432 break;
... ... @@ -3202,6 +3284,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3202 3284 gen_op_st_T0_A0[ot]();
3203 3285 else
3204 3286 gen_op_mov_reg_T0[ot][rm]();
  3287 + gen_op_update_bt_cc();
3205 3288 }
3206 3289 break;
3207 3290 case 0x1a3: /* bt Gv, Ev */
... ... @@ -3240,6 +3323,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3240 3323 gen_op_st_T0_A0[ot]();
3241 3324 else
3242 3325 gen_op_mov_reg_T0[ot][rm]();
  3326 + gen_op_update_bt_cc();
3243 3327 }
3244 3328 break;
3245 3329 case 0x1bc: /* bsf */
... ... @@ -3640,6 +3724,13 @@ static uint16_t opc_read_flags[NB_OPS] = {
3640 3724 [INDEX_op_sbbw_T0_T1_cc] = CC_C,
3641 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 3734 /* subtle: due to the incl/decl implementation, C is used */
3644 3735 [INDEX_op_update_inc_cc] = CC_C,
3645 3736  
... ... @@ -3717,23 +3808,38 @@ static uint16_t opc_read_flags[NB_OPS] = {
3717 3808 [INDEX_op_rcrb_T0_T1_cc] = CC_C,
3718 3809 [INDEX_op_rcrw_T0_T1_cc] = CC_C,
3719 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 3820 /* flags written by an operation */
3723 3821 static uint16_t opc_write_flags[NB_OPS] = {
3724 3822 [INDEX_op_update2_cc] = CC_OSZAPC,
3725 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 3830 [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
3727 3831 [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
3728 3832 [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
3729 3833 [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
3730 3834 [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
3731 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 3844 [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
3739 3845 [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
... ... @@ -3795,6 +3901,42 @@ static uint16_t opc_write_flags[NB_OPS] = {
3795 3901 [INDEX_op_shrdw_T0_T1_im_cc] = CC_OSZAPC,
3796 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 3940 [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
3799 3941 [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
3800 3942 [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
... ... @@ -3832,6 +3974,10 @@ static uint16_t opc_write_flags[NB_OPS] = {
3832 3974 [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
3833 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 3981 [INDEX_op_cmpxchg8b] = CC_Z,
3836 3982 [INDEX_op_lar] = CC_Z,
3837 3983 [INDEX_op_lsl] = CC_Z,
... ... @@ -3844,8 +3990,10 @@ static uint16_t opc_simpler[NB_OPS] = {
3844 3990 [INDEX_op_update2_cc] = INDEX_op_nop,
3845 3991 [INDEX_op_update1_cc] = INDEX_op_nop,
3846 3992 [INDEX_op_update_neg_cc] = INDEX_op_nop,
  3993 +#if 0
  3994 + /* broken: CC_OP logic must be rewritten */
3847 3995 [INDEX_op_update_inc_cc] = INDEX_op_nop,
3848   -
  3996 +#endif
3849 3997 [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
3850 3998 [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,
3851 3999 [INDEX_op_roll_T0_T1_cc] = INDEX_op_roll_T0_T1,
... ... @@ -3854,6 +4002,14 @@ static uint16_t opc_simpler[NB_OPS] = {
3854 4002 [INDEX_op_rorw_T0_T1_cc] = INDEX_op_rorw_T0_T1,
3855 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 4013 [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
3858 4014 [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
3859 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 4127 break;
3972 4128 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
3973 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 4134 /* we must store the eflags state if it is not already done */
3975 4135 if (dc->is_jmp != DISAS_TB_JUMP) {
3976 4136 if (dc->cc_op != CC_OP_DYNAMIC)
... ... @@ -3983,12 +4143,19 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc
3983 4143 if (dc->tf) {
3984 4144 gen_op_raise_exception(EXCP01_SSTP);
3985 4145 }
3986   - if (dc->is_jmp != 3) {
  4146 + if (dc->is_jmp != DISAS_TB_JUMP) {
3987 4147 /* indicate that the hash table must be used to find the next TB */
3988 4148 gen_op_movl_T0_0();
3989 4149 }
3990 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 4159 #ifdef DEBUG_DISAS
3993 4160 if (loglevel) {
3994 4161 fprintf(logfile, "----------------\n");
... ...