summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-06-30 23:36:57 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-06-30 23:36:57 +0000
commite477b8b81ba5212747799ce71858e2b110fc6ae5 (patch)
treeb25d335ce7fa2dd3fc67dc858023e94a9ea309db
parentb118d61e556a1f5cebc991e368af7292ffa1d8f3 (diff)
downloadqemu-e477b8b81ba5212747799ce71858e2b110fc6ae5.tar.gz
correct eflags evaluation order for all operations - fixed important CPU state restoring 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
-rw-r--r--Makefile2
-rw-r--r--dyngen.c8
-rw-r--r--ops_template.h321
-rw-r--r--ops_template_mem.h423
-rw-r--r--translate-i386.c221
5 files changed, 636 insertions, 339 deletions
diff --git a/Makefile b/Makefile
index 6d6458eb5e..0fa0fa303d 100644
--- a/Makefile
+++ b/Makefile
@@ -174,7 +174,7 @@ op-$(TARGET_ARCH).o: op-$(TARGET_ARCH).c
helper-$(TARGET_ARCH).o: helper-$(TARGET_ARCH).c
$(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<
-op-i386.o: op-i386.c opreg_template.h ops_template.h
+op-i386.o: op-i386.c opreg_template.h ops_template.h ops_template_mem.h
op-arm.o: op-arm.c op-arm-template.h
diff --git a/dyngen.c b/dyngen.c
index 3e846232b4..c6c373bd1a 100644
--- a/dyngen.c
+++ b/dyngen.c
@@ -1200,11 +1200,11 @@ int load_elf(const char *filename, FILE *outfile, int out_type)
}
if (out_type == OUT_INDEX_OP) {
- fprintf(outfile, "DEF(nop1, 0, 0)\n");
- fprintf(outfile, "DEF(nop2, 0, 0)\n");
- fprintf(outfile, "DEF(nop3, 0, 0)\n");
- fprintf(outfile, "DEF(nop, 0, 0)\n");
fprintf(outfile, "DEF(end, 0, 0)\n");
+ fprintf(outfile, "DEF(nop, 0, 0)\n");
+ fprintf(outfile, "DEF(nop1, 1, 0)\n");
+ fprintf(outfile, "DEF(nop2, 2, 0)\n");
+ fprintf(outfile, "DEF(nop3, 3, 0)\n");
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
const char *name, *p;
name = strtab + sym->st_name;
diff --git a/ops_template.h b/ops_template.h
index c6e2b6b971..4595291e78 100644
--- a/ops_template.h
+++ b/ops_template.h
@@ -406,127 +406,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
/* shifts */
-void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
-{
- int count, src;
- count = T1 & SHIFT_MASK;
- if (count) {
- CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
- src = T0;
- T0 &= DATA_MASK;
- T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
- CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- (T0 & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
-{
- int count, src;
- count = T1 & SHIFT_MASK;
- if (count) {
- CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
- src = T0;
- T0 &= DATA_MASK;
- T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
- CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((T0 >> (DATA_BITS - 1)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1)(void)
-{
- int count;
- count = T1 & SHIFT_MASK;
- if (count) {
- T0 &= DATA_MASK;
- T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
-{
- int count, res, eflags;
- unsigned int src;
-
- count = T1 & 0x1f;
-#if DATA_BITS == 16
- count = rclw_table[count];
-#elif DATA_BITS == 8
- count = rclb_table[count];
-#endif
- if (count) {
- eflags = cc_table[CC_OP].compute_all();
- T0 &= DATA_MASK;
- src = T0;
- res = (T0 << count) | ((eflags & CC_C) << (count - 1));
- if (count > 1)
- res |= T0 >> (DATA_BITS + 1 - count);
- T0 = res;
- CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((src >> (DATA_BITS - count)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
-{
- int count, res, eflags;
- unsigned int src;
-
- count = T1 & 0x1f;
-#if DATA_BITS == 16
- count = rclw_table[count];
-#elif DATA_BITS == 8
- count = rclb_table[count];
-#endif
- if (count) {
- eflags = cc_table[CC_OP].compute_all();
- T0 &= DATA_MASK;
- src = T0;
- res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
- if (count > 1)
- res |= T0 << (DATA_BITS + 1 - count);
- T0 = res;
- CC_SRC = (eflags & ~(CC_C | CC_O)) |
- (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
- ((src >> (count - 1)) & CC_C);
- CC_OP = CC_OP_EFLAGS;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & 0x1f;
- if (count) {
- CC_SRC = (DATA_TYPE)T0 << (count - 1);
- T0 = T0 << count;
- CC_DST = T0;
- CC_OP = CC_OP_SHLB + SHIFT;
- }
- FORCE_RET();
-}
-
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
{
int count;
@@ -535,20 +414,6 @@ void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
FORCE_RET();
}
-void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
-{
- int count;
- count = T1 & 0x1f;
- if (count) {
- T0 &= DATA_MASK;
- CC_SRC = T0 >> (count - 1);
- T0 = T0 >> count;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
{
int count;
@@ -558,20 +423,6 @@ void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
FORCE_RET();
}
-void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
-{
- int count, src;
- count = T1 & 0x1f;
- if (count) {
- src = (DATA_STYPE)T0;
- CC_SRC = src >> (count - 1);
- T0 = src >> count;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
{
int count, src;
@@ -581,162 +432,11 @@ void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
FORCE_RET();
}
-#if DATA_BITS == 16
-/* XXX: overflow flag might be incorrect in some cases in shldw */
-void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- unsigned int res;
- count = PARAM1;
- T1 &= 0xffff;
- res = T1 | (T0 << 16);
- CC_SRC = res >> (32 - count);
- res <<= count;
- if (count > 16)
- res |= T1 << (count - 16);
- T0 = res >> 16;
- CC_DST = T0;
-}
-
-void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- unsigned int res;
- count = ECX & 0x1f;
- if (count) {
- T1 &= 0xffff;
- res = T1 | (T0 << 16);
- CC_SRC = res >> (32 - count);
- res <<= count;
- if (count > 16)
- res |= T1 << (count - 16);
- T0 = res >> 16;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- unsigned int res;
-
- count = PARAM1;
- res = (T0 & 0xffff) | (T1 << 16);
- CC_SRC = res >> (count - 1);
- res >>= count;
- if (count > 16)
- res |= T1 << (32 - count);
- T0 = res;
- CC_DST = T0;
-}
-
-
-void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- unsigned int res;
-
- count = ECX & 0x1f;
- if (count) {
- res = (T0 & 0xffff) | (T1 << 16);
- CC_SRC = res >> (count - 1);
- res >>= count;
- if (count > 16)
- res |= T1 << (32 - count);
- T0 = res;
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-#endif
-
-#if DATA_BITS == 32
-void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- count = PARAM1;
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- CC_SRC = T0 << (count - 1);
- T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
- CC_DST = T0;
-}
-
-void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- count = ECX & 0x1f;
- if (count) {
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- CC_SRC = T0 << (count - 1);
- T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
- CC_DST = T0;
- CC_OP = CC_OP_SHLB + SHIFT;
- }
- FORCE_RET();
-}
-
-void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
-{
- int count;
- count = PARAM1;
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- CC_SRC = T0 >> (count - 1);
- T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
- CC_DST = T0;
-}
+#undef MEM_WRITE
+#include "ops_template_mem.h"
-
-void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
-{
- int count;
- count = ECX & 0x1f;
- if (count) {
- T0 &= DATA_MASK;
- T1 &= DATA_MASK;
- CC_SRC = T0 >> (count - 1);
- T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
- CC_DST = T0;
- CC_OP = CC_OP_SARB + SHIFT;
- }
- FORCE_RET();
-}
-#endif
-
-/* carry add/sub (we only need to set CC_OP differently) */
-
-void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
-{
- int cf;
- cf = cc_table[CC_OP].compute_c();
- T0 = T0 + T1 + cf;
- CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
-}
-
-void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
-{
- int cf;
- cf = cc_table[CC_OP].compute_c();
- T0 = T0 - T1 - cf;
- CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
-}
-
-void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void)
-{
- CC_SRC = T0;
- CC_DST = EAX - T0;
- if ((DATA_TYPE)CC_DST == 0) {
- T0 = T1;
- } else {
- EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
- }
- FORCE_RET();
-}
+#define MEM_WRITE
+#include "ops_template_mem.h"
/* bit operations */
#if DATA_BITS >= 16
@@ -752,7 +452,7 @@ void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
{
int count;
count = T1 & SHIFT_MASK;
- CC_SRC = T0 >> count;
+ T1 = T0 >> count;
T0 |= (1 << count);
}
@@ -760,7 +460,7 @@ void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
{
int count;
count = T1 & SHIFT_MASK;
- CC_SRC = T0 >> count;
+ T1 = T0 >> count;
T0 &= ~(1 << count);
}
@@ -768,7 +468,7 @@ void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
{
int count;
count = T1 & SHIFT_MASK;
- CC_SRC = T0 >> count;
+ T1 = T0 >> count;
T0 ^= (1 << count);
}
@@ -810,6 +510,13 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
#endif
+#if DATA_BITS == 32
+void OPPROTO op_update_bt_cc(void)
+{
+ CC_SRC = T1;
+}
+#endif
+
/* string operations */
/* XXX: maybe use lower level instructions to ease 16 bit / segment handling */
diff --git a/ops_template_mem.h b/ops_template_mem.h
new file mode 100644
index 0000000000..f1209d2aa0
--- /dev/null
+++ b/ops_template_mem.h
@@ -0,0 +1,423 @@
+/*
+ * i386 micro operations (included several times to generate
+ * different operand sizes)
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifdef MEM_WRITE
+
+#if DATA_BITS == 8
+#define MEM_SUFFIX b_mem
+#elif DATA_BITS == 16
+#define MEM_SUFFIX w_mem
+#elif DATA_BITS == 32
+#define MEM_SUFFIX l_mem
+#endif
+
+#else
+
+#define MEM_SUFFIX SUFFIX
+
+#endif
+
+void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int count, src;
+ count = T1 & SHIFT_MASK;
+ if (count) {
+ src = T0;
+ T0 &= DATA_MASK;
+ T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ (T0 & CC_C);
+ CC_OP = CC_OP_EFLAGS;
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int count, src;
+ count = T1 & SHIFT_MASK;
+ if (count) {
+ src = T0;
+ T0 &= DATA_MASK;
+ T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = (cc_table[CC_OP].compute_all() & ~(CC_O | CC_C)) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ ((T0 >> (DATA_BITS - 1)) & CC_C);
+ CC_OP = CC_OP_EFLAGS;
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_rol, MEM_SUFFIX), _T0_T1)(void)
+{
+ int count;
+ count = T1 & SHIFT_MASK;
+ if (count) {
+ T0 &= DATA_MASK;
+ T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_ror, MEM_SUFFIX), _T0_T1)(void)
+{
+ int count;
+ count = T1 & SHIFT_MASK;
+ if (count) {
+ T0 &= DATA_MASK;
+ T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_rcl, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int count, res, eflags;
+ unsigned int src;
+
+ count = T1 & 0x1f;
+#if DATA_BITS == 16
+ count = rclw_table[count];
+#elif DATA_BITS == 8
+ count = rclb_table[count];
+#endif
+ if (count) {
+ eflags = cc_table[CC_OP].compute_all();
+ T0 &= DATA_MASK;
+ src = T0;
+ res = (T0 << count) | ((eflags & CC_C) << (count - 1));
+ if (count > 1)
+ res |= T0 >> (DATA_BITS + 1 - count);
+ T0 = res;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = (eflags & ~(CC_C | CC_O)) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ ((src >> (DATA_BITS - count)) & CC_C);
+ CC_OP = CC_OP_EFLAGS;
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_rcr, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int count, res, eflags;
+ unsigned int src;
+
+ count = T1 & 0x1f;
+#if DATA_BITS == 16
+ count = rclw_table[count];
+#elif DATA_BITS == 8
+ count = rclb_table[count];
+#endif
+ if (count) {
+ eflags = cc_table[CC_OP].compute_all();
+ T0 &= DATA_MASK;
+ src = T0;
+ res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
+ if (count > 1)
+ res |= T0 << (DATA_BITS + 1 - count);
+ T0 = res;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = (eflags & ~(CC_C | CC_O)) |
+ (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
+ ((src >> (count - 1)) & CC_C);
+ CC_OP = CC_OP_EFLAGS;
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_shl, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int count, src;
+ count = T1 & 0x1f;
+ if (count) {
+ src = (DATA_TYPE)T0 << (count - 1);
+ T0 = T0 << count;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = src;
+ CC_DST = T0;
+ CC_OP = CC_OP_SHLB + SHIFT;
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_shr, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int count, src;
+ count = T1 & 0x1f;
+ if (count) {
+ T0 &= DATA_MASK;
+ src = T0 >> (count - 1);
+ T0 = T0 >> count;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = src;
+ CC_DST = T0;
+ CC_OP = CC_OP_SARB + SHIFT;
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_sar, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int count, src;
+ count = T1 & 0x1f;
+ if (count) {
+ src = (DATA_STYPE)T0;
+ T0 = src >> count;
+ src = src >> (count - 1);
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = src;
+ CC_DST = T0;
+ CC_OP = CC_OP_SARB + SHIFT;
+ }
+ FORCE_RET();
+}
+
+#if DATA_BITS == 16
+/* XXX: overflow flag might be incorrect in some cases in shldw */
+void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
+{
+ int count;
+ unsigned int res, tmp;
+ count = PARAM1;
+ T1 &= 0xffff;
+ res = T1 | (T0 << 16);
+ tmp = res >> (32 - count);
+ res <<= count;
+ if (count > 16)
+ res |= T1 << (count - 16);
+ T0 = res >> 16;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = tmp;
+ CC_DST = T0;
+}
+
+void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
+{
+ int count;
+ unsigned int res, tmp;
+ count = ECX & 0x1f;
+ if (count) {
+ T1 &= 0xffff;
+ res = T1 | (T0 << 16);
+ tmp = res >> (32 - count);
+ res <<= count;
+ if (count > 16)
+ res |= T1 << (count - 16);
+ T0 = res >> 16;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = tmp;
+ CC_DST = T0;
+ CC_OP = CC_OP_SARB + SHIFT;
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
+{
+ int count;
+ unsigned int res, tmp;
+
+ count = PARAM1;
+ res = (T0 & 0xffff) | (T1 << 16);
+ tmp = res >> (count - 1);
+ res >>= count;
+ if (count > 16)
+ res |= T1 << (32 - count);
+ T0 = res;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = tmp;
+ CC_DST = T0;
+}
+
+
+void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
+{
+ int count;
+ unsigned int res, tmp;
+
+ count = ECX & 0x1f;
+ if (count) {
+ res = (T0 & 0xffff) | (T1 << 16);
+ tmp = res >> (count - 1);
+ res >>= count;
+ if (count > 16)
+ res |= T1 << (32 - count);
+ T0 = res;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = tmp;
+ CC_DST = T0;
+ CC_OP = CC_OP_SARB + SHIFT;
+ }
+ FORCE_RET();
+}
+#endif
+
+#if DATA_BITS == 32
+void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_im_cc)(void)
+{
+ int count, tmp;
+ count = PARAM1;
+ T0 &= DATA_MASK;
+ T1 &= DATA_MASK;
+ tmp = T0 << (count - 1);
+ T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = tmp;
+ CC_DST = T0;
+}
+
+void OPPROTO glue(glue(op_shld, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
+{
+ int count, tmp;
+ count = ECX & 0x1f;
+ if (count) {
+ T0 &= DATA_MASK;
+ T1 &= DATA_MASK;
+ tmp = T0 << (count - 1);
+ T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = tmp;
+ CC_DST = T0;
+ CC_OP = CC_OP_SHLB + SHIFT;
+ }
+ FORCE_RET();
+}
+
+void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_im_cc)(void)
+{
+ int count, tmp;
+ count = PARAM1;
+ T0 &= DATA_MASK;
+ T1 &= DATA_MASK;
+ tmp = T0 >> (count - 1);
+ T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = tmp;
+ CC_DST = T0;
+}
+
+
+void OPPROTO glue(glue(op_shrd, MEM_SUFFIX), _T0_T1_ECX_cc)(void)
+{
+ int count, tmp;
+ count = ECX & 0x1f;
+ if (count) {
+ T0 &= DATA_MASK;
+ T1 &= DATA_MASK;
+ tmp = T0 >> (count - 1);
+ T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = tmp;
+ CC_DST = T0;
+ CC_OP = CC_OP_SARB + SHIFT;
+ }
+ FORCE_RET();
+}
+#endif
+
+/* carry add/sub (we only need to set CC_OP differently) */
+
+void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int cf;
+ cf = cc_table[CC_OP].compute_c();
+ T0 = T0 + T1 + cf;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = T1;
+ CC_DST = T0;
+ CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
+}
+
+void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void)
+{
+ int cf;
+ cf = cc_table[CC_OP].compute_c();
+ T0 = T0 - T1 - cf;
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = T1;
+ CC_DST = T0;
+ CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
+}
+
+void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void)
+{
+ unsigned int src, dst;
+
+ src = T0;
+ dst = EAX - T0;
+ if ((DATA_TYPE)dst == 0) {
+ T0 = T1;
+ } else {
+ EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
+ }
+#ifdef MEM_WRITE
+ glue(st, SUFFIX)((uint8_t *)A0, T0);
+#endif
+ CC_SRC = src;
+ CC_DST = dst;
+ FORCE_RET();
+}
+
+#undef MEM_SUFFIX
+#undef MEM_WRITE
diff --git a/translate-i386.c b/translate-i386.c
index 8a7147c556..bfc988446e 100644
--- a/translate-i386.c
+++ b/translate-i386.c
@@ -390,6 +390,21 @@ static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
},
};
+static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3][2] = {
+ [OT_BYTE] = {
+ gen_op_adcb_mem_T0_T1_cc,
+ gen_op_sbbb_mem_T0_T1_cc,
+ },
+ [OT_WORD] = {
+ gen_op_adcw_mem_T0_T1_cc,
+ gen_op_sbbw_mem_T0_T1_cc,
+ },
+ [OT_LONG] = {
+ gen_op_adcl_mem_T0_T1_cc,
+ gen_op_sbbl_mem_T0_T1_cc,
+ },
+};
+
static const int cc_op_arithb[8] = {
CC_OP_ADDB,
CC_OP_LOGICB,
@@ -407,6 +422,12 @@ static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = {
gen_op_cmpxchgl_T0_T1_EAX_cc,
};
+static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3] = {
+ gen_op_cmpxchgb_mem_T0_T1_EAX_cc,
+ gen_op_cmpxchgw_mem_T0_T1_EAX_cc,
+ gen_op_cmpxchgl_mem_T0_T1_EAX_cc,
+};
+
static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
[OT_BYTE] = {
gen_op_rolb_T0_T1_cc,
@@ -440,6 +461,39 @@ static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
},
};
+static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3][8] = {
+ [OT_BYTE] = {
+ gen_op_rolb_mem_T0_T1_cc,
+ gen_op_rorb_mem_T0_T1_cc,
+ gen_op_rclb_mem_T0_T1_cc,
+ gen_op_rcrb_mem_T0_T1_cc,
+ gen_op_shlb_mem_T0_T1_cc,
+ gen_op_shrb_mem_T0_T1_cc,
+ gen_op_shlb_mem_T0_T1_cc,
+ gen_op_sarb_mem_T0_T1_cc,
+ },
+ [OT_WORD] = {
+ gen_op_rolw_mem_T0_T1_cc,
+ gen_op_rorw_mem_T0_T1_cc,
+ gen_op_rclw_mem_T0_T1_cc,
+ gen_op_rcrw_mem_T0_T1_cc,
+ gen_op_shlw_mem_T0_T1_cc,
+ gen_op_shrw_mem_T0_T1_cc,
+ gen_op_shlw_mem_T0_T1_cc,
+ gen_op_sarw_mem_T0_T1_cc,
+ },
+ [OT_LONG] = {
+ gen_op_roll_mem_T0_T1_cc,
+ gen_op_rorl_mem_T0_T1_cc,
+ gen_op_rcll_mem_T0_T1_cc,
+ gen_op_rcrl_mem_T0_T1_cc,
+ gen_op_shll_mem_T0_T1_cc,
+ gen_op_shrl_mem_T0_T1_cc,
+ gen_op_shll_mem_T0_T1_cc,
+ gen_op_sarl_mem_T0_T1_cc,
+ },
+};
+
static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = {
[0] = {
gen_op_shldw_T0_T1_im_cc,
@@ -462,6 +516,28 @@ static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = {
},
};
+static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[2][2] = {
+ [0] = {
+ gen_op_shldw_mem_T0_T1_im_cc,
+ gen_op_shrdw_mem_T0_T1_im_cc,
+ },
+ [1] = {
+ gen_op_shldl_mem_T0_T1_im_cc,
+ gen_op_shrdl_mem_T0_T1_im_cc,
+ },
+};
+
+static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[2][2] = {
+ [0] = {
+ gen_op_shldw_mem_T0_T1_ECX_cc,
+ gen_op_shrdw_mem_T0_T1_ECX_cc,
+ },
+ [1] = {
+ gen_op_shldl_mem_T0_T1_ECX_cc,
+ gen_op_shrdl_mem_T0_T1_ECX_cc,
+ },
+};
+
static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
[0] = {
gen_op_btw_T0_T1_cc,
@@ -763,11 +839,14 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
case OP_SBBL:
if (s1->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s1->cc_op);
- gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
+ if (d != OR_TMP0) {
+ gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
+ gen_op_mov_reg_T0[ot][d]();
+ } else {
+ gen_op_arithc_mem_T0_T1_cc[ot][op - OP_ADCL]();
+ }
s1->cc_op = CC_OP_DYNAMIC;
- /* XXX: incorrect: CC_OP must also be modified AFTER memory access */
- gen_update_cc = gen_op_update2_cc;
- break;
+ goto the_end;
case OP_ADDL:
gen_op_addl_T0_T1();
s1->cc_op = CC_OP_ADDB + ot;
@@ -802,6 +881,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
exception support) */
if (gen_update_cc)
gen_update_cc();
+ the_end: ;
}
/* 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)
{
if (d != OR_TMP0)
gen_op_mov_TN_reg[ot][0][d]();
+ else
+ gen_op_ld_T0_A0[ot]();
if (s != OR_TMP1)
gen_op_mov_TN_reg[ot][1][s]();
/* for zero counts, flags are not updated, so must do it dynamically */
if (s1->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s1->cc_op);
-
- gen_op_shift_T0_T1_cc[ot][op]();
-
+
+ if (d != OR_TMP0)
+ gen_op_shift_T0_T1_cc[ot][op]();
+ else
+ gen_op_shift_mem_T0_T1_cc[ot][op]();
if (d != OR_TMP0)
gen_op_mov_reg_T0[ot][d]();
s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
@@ -1885,8 +1969,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
} else {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
gen_op_ld_T0_A0[ot]();
- gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
- gen_op_st_T0_A0[ot]();
+ gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot]();
}
s->cc_op = CC_OP_SUBB + ot;
break;
@@ -2264,7 +2347,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
if (mod != 3) {
gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
- gen_op_ld_T0_A0[ot]();
opreg = OR_TMP0;
} else {
opreg = rm + OR_EAX;
@@ -2279,10 +2361,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
}
gen_shifti(s, op, ot, opreg, shift);
}
-
- if (mod != 3) {
- gen_op_st_T0_A0[ot]();
- }
}
break;
case 0xd0:
@@ -2330,7 +2408,10 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
val = ldub(s->pc++);
val &= 0x1f;
if (val) {
- gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
+ if (mod == 3)
+ gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
+ else
+ gen_op_shiftd_mem_T0_T1_im_cc[ot - OT_WORD][op](val);
if (op == 0 && ot != OT_WORD)
s->cc_op = CC_OP_SHLB + ot;
else
@@ -2339,12 +2420,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
} else {
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
- gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
+ if (mod == 3)
+ gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
+ else
+ gen_op_shiftd_mem_T0_T1_ECX_cc[ot - OT_WORD][op]();
s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
}
- if (mod != 3) {
- gen_op_st_T0_A0[ot]();
- } else {
+ if (mod == 3) {
gen_op_mov_reg_T0[ot][rm]();
}
break;
@@ -3202,6 +3284,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_st_T0_A0[ot]();
else
gen_op_mov_reg_T0[ot][rm]();
+ gen_op_update_bt_cc();
}
break;
case 0x1a3: /* bt Gv, Ev */
@@ -3240,6 +3323,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_st_T0_A0[ot]();
else
gen_op_mov_reg_T0[ot][rm]();
+ gen_op_update_bt_cc();
}
break;
case 0x1bc: /* bsf */
@@ -3640,6 +3724,13 @@ static uint16_t opc_read_flags[NB_OPS] = {
[INDEX_op_sbbw_T0_T1_cc] = CC_C,
[INDEX_op_sbbl_T0_T1_cc] = CC_C,
+ [INDEX_op_adcb_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_adcw_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_adcl_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_sbbb_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_sbbw_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_sbbl_mem_T0_T1_cc] = CC_C,
+
/* subtle: due to the incl/decl implementation, C is used */
[INDEX_op_update_inc_cc] = CC_C,
@@ -3717,23 +3808,38 @@ static uint16_t opc_read_flags[NB_OPS] = {
[INDEX_op_rcrb_T0_T1_cc] = CC_C,
[INDEX_op_rcrw_T0_T1_cc] = CC_C,
[INDEX_op_rcrl_T0_T1_cc] = CC_C,
+
+ [INDEX_op_rclb_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_rclw_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_rcll_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_rcrb_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_rcrw_mem_T0_T1_cc] = CC_C,
+ [INDEX_op_rcrl_mem_T0_T1_cc] = CC_C,
};
/* flags written by an operation */
static uint16_t opc_write_flags[NB_OPS] = {
[INDEX_op_update2_cc] = CC_OSZAPC,
[INDEX_op_update1_cc] = CC_OSZAPC,
+ [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_update_neg_cc] = CC_OSZAPC,
+ /* subtle: due to the incl/decl implementation, C is used */
+ [INDEX_op_update_inc_cc] = CC_OSZAPC,
+ [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
+
[INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,
- [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
- [INDEX_op_update_neg_cc] = CC_OSZAPC,
- /* subtle: due to the incl/decl implementation, C is used */
- [INDEX_op_update_inc_cc] = CC_OSZAPC,
- [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
+
+ [INDEX_op_adcb_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_adcw_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_adcl_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_sbbb_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_sbbw_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_sbbl_mem_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_mulb_AL_T0] = CC_OSZAPC,
[INDEX_op_imulb_AL_T0] = CC_OSZAPC,
@@ -3795,6 +3901,42 @@ static uint16_t opc_write_flags[NB_OPS] = {
[INDEX_op_shrdw_T0_T1_im_cc] = CC_OSZAPC,
[INDEX_op_shrdl_T0_T1_im_cc] = CC_OSZAPC,
+ [INDEX_op_rolb_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rolw_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_roll_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rorb_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rorw_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rorl_mem_T0_T1_cc] = CC_O | CC_C,
+
+ [INDEX_op_rclb_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rclw_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rcll_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rcrb_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rcrw_mem_T0_T1_cc] = CC_O | CC_C,
+ [INDEX_op_rcrl_mem_T0_T1_cc] = CC_O | CC_C,
+
+ [INDEX_op_shlb_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_shlw_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_shll_mem_T0_T1_cc] = CC_OSZAPC,
+
+ [INDEX_op_shrb_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_shrw_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_shrl_mem_T0_T1_cc] = CC_OSZAPC,
+
+ [INDEX_op_sarb_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_sarw_mem_T0_T1_cc] = CC_OSZAPC,
+ [INDEX_op_sarl_mem_T0_T1_cc] = CC_OSZAPC,
+
+ [INDEX_op_shldw_mem_T0_T1_ECX_cc] = CC_OSZAPC,
+ [INDEX_op_shldl_mem_T0_T1_ECX_cc] = CC_OSZAPC,
+ [INDEX_op_shldw_mem_T0_T1_im_cc] = CC_OSZAPC,
+ [INDEX_op_shldl_mem_T0_T1_im_cc] = CC_OSZAPC,
+
+ [INDEX_op_shrdw_mem_T0_T1_ECX_cc] = CC_OSZAPC,
+ [INDEX_op_shrdl_mem_T0_T1_ECX_cc] = CC_OSZAPC,
+ [INDEX_op_shrdw_mem_T0_T1_im_cc] = CC_OSZAPC,
+ [INDEX_op_shrdl_mem_T0_T1_im_cc] = CC_OSZAPC,
+
[INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
[INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
@@ -3832,6 +3974,10 @@ static uint16_t opc_write_flags[NB_OPS] = {
[INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
[INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
+ [INDEX_op_cmpxchgb_mem_T0_T1_EAX_cc] = CC_OSZAPC,
+ [INDEX_op_cmpxchgw_mem_T0_T1_EAX_cc] = CC_OSZAPC,
+ [INDEX_op_cmpxchgl_mem_T0_T1_EAX_cc] = CC_OSZAPC,
+
[INDEX_op_cmpxchg8b] = CC_Z,
[INDEX_op_lar] = CC_Z,
[INDEX_op_lsl] = CC_Z,
@@ -3844,8 +3990,10 @@ static uint16_t opc_simpler[NB_OPS] = {
[INDEX_op_update2_cc] = INDEX_op_nop,
[INDEX_op_update1_cc] = INDEX_op_nop,
[INDEX_op_update_neg_cc] = INDEX_op_nop,
+#if 0
+ /* broken: CC_OP logic must be rewritten */
[INDEX_op_update_inc_cc] = INDEX_op_nop,
-
+#endif
[INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
[INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,
[INDEX_op_roll_T0_T1_cc] = INDEX_op_roll_T0_T1,
@@ -3854,6 +4002,14 @@ static uint16_t opc_simpler[NB_OPS] = {
[INDEX_op_rorw_T0_T1_cc] = INDEX_op_rorw_T0_T1,
[INDEX_op_rorl_T0_T1_cc] = INDEX_op_rorl_T0_T1,
+ [INDEX_op_rolb_mem_T0_T1_cc] = INDEX_op_rolb_mem_T0_T1,
+ [INDEX_op_rolw_mem_T0_T1_cc] = INDEX_op_rolw_mem_T0_T1,
+ [INDEX_op_roll_mem_T0_T1_cc] = INDEX_op_roll_mem_T0_T1,
+
+ [INDEX_op_rorb_mem_T0_T1_cc] = INDEX_op_rorb_mem_T0_T1,
+ [INDEX_op_rorw_mem_T0_T1_cc] = INDEX_op_rorw_mem_T0_T1,
+ [INDEX_op_rorl_mem_T0_T1_cc] = INDEX_op_rorl_mem_T0_T1,
+
[INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
[INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
[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
break;
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
(pc_ptr - pc_start) < (TARGET_PAGE_SIZE - 32));
+ if (!dc->tf && dc->is_jmp == DISAS_NEXT) {
+ gen_jmp(dc, ret - (unsigned long)dc->cs_base);
+ }
+
/* we must store the eflags state if it is not already done */
if (dc->is_jmp != DISAS_TB_JUMP) {
if (dc->cc_op != CC_OP_DYNAMIC)
@@ -3983,12 +4143,19 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc
if (dc->tf) {
gen_op_raise_exception(EXCP01_SSTP);
}
- if (dc->is_jmp != 3) {
+ if (dc->is_jmp != DISAS_TB_JUMP) {
/* indicate that the hash table must be used to find the next TB */
gen_op_movl_T0_0();
}
*gen_opc_ptr = INDEX_op_end;
-
+ /* we don't forget to fill the last values */
+ if (search_pc) {
+ j = gen_opc_ptr - gen_opc_buf;
+ lj++;
+ while (lj <= j)
+ gen_opc_instr_start[lj++] = 0;
+ }
+
#ifdef DEBUG_DISAS
if (loglevel) {
fprintf(logfile, "----------------\n");