Bochs/bochs/patches/patch.extra_eflags_asms

712 lines
19 KiB
Plaintext
Raw Normal View History

----------------------------------------------------------------------
Patch name: patch.extra_eflags_asms
Author: Jas Sandys-Lumsdaine
Date: Wed Oct 2 01:36:15 GMT 2002
Detailed description:
This patch adds extra inline asm statements for the most important
instructions I found to be still resorting to lazy flags execution.
I counted the instructions that "hit" and "missed" when an eflag
value was needed - if there was a miss, the flag was not known and
had to be calculated with lazy_flags.cc. The culprit instruction
which last executed to affect the eflags was tallied.
The boot sequences for dlxlinux and win98 were used - win98 gave many
more cases than dlxlinux which was covered more or less by Kevin's
original asm additions. Now 1.5% or less of eflags accesses have to
resort to lazy_flags (a "miss").
Patch was created with:
cvs diff -u
Apply patch to what version:
cvs checked out on Oct 2
Instructions:
To patch, go to main bochs directory.
Type "patch -p0 < THIS_PATCH_FILE".
----------------------------------------------------------------------
Index: cpu/arith16.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/arith16.cc,v
retrieving revision 1.22
diff -u -r1.22 arith16.cc
--- cpu/arith16.cc 30 Sep 2002 02:02:06 -0000 1.22
+++ cpu/arith16.cc 2 Oct 2002 00:34:30 -0000
@@ -370,16 +370,48 @@
if (i->modC0()) {
op1_16 = BX_READ_16BIT_REG(i->rm());
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
+#endif
BX_WRITE_16BIT_REG(i->rm(), diff_16);
}
else {
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
+#endif
Write_RMW_virtual_word(diff_16);
}
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+#endif
}
@@ -397,11 +429,28 @@
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
}
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
+#endif
BX_WRITE_16BIT_REG(i->nnn(), diff_16);
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+#endif
}
void
@@ -412,11 +461,28 @@
op1_16 = AX;
op2_16 = i->Iw();
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
+#endif
AX = diff_16;
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+#endif
}
@@ -687,16 +753,48 @@
if (i->modC0()) {
op1_16 = BX_READ_16BIT_REG(i->rm());
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
+#endif
BX_WRITE_16BIT_REG(i->rm(), diff_16);
}
else {
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
+#endif
Write_RMW_virtual_word(diff_16);
}
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+#endif
}
void
@@ -784,16 +882,48 @@
if (i->modC0()) {
op1_16 = BX_READ_16BIT_REG(i->rm());
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "decw %1 \n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (op1_16)
+ : "1" (op1_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPMask) | (flags32 & EFlagsOSZAPMask);
+ BX_CPU_THIS_PTR lf_flags_status &= 0x00000f;
+#else
op1_16--;
+#endif
BX_WRITE_16BIT_REG(i->rm(), op1_16);
}
else {
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "decw %1 \n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (op1_16)
+ : "1" (op1_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPMask) | (flags32 & EFlagsOSZAPMask);
+ BX_CPU_THIS_PTR lf_flags_status &= 0x00000f;
+#else
op1_16--;
+#endif
Write_RMW_virtual_word(op1_16);
- }
+ }
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_DEC16);
+#endif
}
Index: cpu/logical16.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/logical16.cc,v
retrieving revision 1.13
diff -u -r1.13 logical16.cc
--- cpu/logical16.cc 30 Sep 2002 03:37:42 -0000 1.13
+++ cpu/logical16.cc 2 Oct 2002 00:34:31 -0000
@@ -41,21 +41,52 @@
{
Bit16u op2_16, op1_16, result_16;
-
op2_16 = BX_READ_16BIT_REG(i->nnn());
if (i->modC0()) {
op1_16 = BX_READ_16BIT_REG(i->rm());
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "xorw %3, %1 \n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (result_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
result_16 = op1_16 ^ op2_16;
+#endif
BX_WRITE_16BIT_REG(i->rm(), result_16);
}
else {
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "xorw %3, %1 \n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (result_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
result_16 = op1_16 ^ op2_16;
+#endif
Write_RMW_virtual_word(result_16);
}
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_XOR16);
+#endif
}
@@ -187,7 +218,6 @@
{
Bit16u op1_16, op2_16, result_16;
-
op1_16 = BX_READ_16BIT_REG(i->nnn());
if (i->modC0()) {
@@ -197,11 +227,28 @@
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
}
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "orw %3, %1 \n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (result_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
result_16 = op1_16 | op2_16;
+#endif
BX_WRITE_16BIT_REG(i->nnn(), result_16);
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_OR16);
+#endif
}
Index: cpu/logical32.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/logical32.cc,v
retrieving revision 1.14
diff -u -r1.14 logical32.cc
--- cpu/logical32.cc 30 Sep 2002 03:37:42 -0000 1.14
+++ cpu/logical32.cc 2 Oct 2002 00:34:33 -0000
@@ -196,11 +196,28 @@
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
}
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "orl %3, %1 \n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (result_32)
+ : "1" (op1_32), "g" (op2_32)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
result_32 = op1_32 | op2_32;
+#endif
BX_WRITE_32BIT_REGZ(i->nnn(), result_32);
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_OR32);
+#endif
}
Index: cpu/logical8.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/logical8.cc,v
retrieving revision 1.15
diff -u -r1.15 logical8.cc
--- cpu/logical8.cc 30 Sep 2002 03:37:42 -0000 1.15
+++ cpu/logical8.cc 2 Oct 2002 00:34:34 -0000
@@ -193,11 +193,28 @@
read_virtual_byte(i->seg(), RMAddr(i), &op2);
}
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "orb %3, %1 \n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (result)
+ : "1" (op1), "g" (op2)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
result = op1 | op2;
+#endif
BX_WRITE_8BIT_REGx(i->nnn(), i->extend8bitL(), result);
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_OR8);
+#endif
}
@@ -209,11 +226,28 @@
op1 = AL;
op2 = i->Ib();
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "orb %3, %1 \n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (sum)
+ : "1" (op1), "g" (op2)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
sum = op1 | op2;
+#endif
AL = sum;
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_OR8);
+#endif
}
Index: cpu/shift16.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/shift16.cc,v
retrieving revision 1.12
diff -u -r1.12 shift16.cc
--- cpu/shift16.cc 22 Sep 2002 18:22:24 -0000 1.12
+++ cpu/shift16.cc 2 Oct 2002 00:34:36 -0000
@@ -432,7 +432,22 @@
if (!count) return;
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "shrw %%cl, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (result_16)
+ : "1" (op1_16), "c" (count)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
result_16 = (op1_16 >> count);
+#endif
/* now write result back to destination */
@@ -443,7 +458,9 @@
Write_RMW_virtual_word(result_16);
}
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHR16);
+#endif
}
Index: cpu/shift32.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/shift32.cc,v
retrieving revision 1.13
diff -u -r1.13 shift32.cc
--- cpu/shift32.cc 22 Sep 2002 18:22:24 -0000 1.13
+++ cpu/shift32.cc 2 Oct 2002 00:34:37 -0000
@@ -397,7 +397,22 @@
if (!count) return;
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "shrl %%cl, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (result_32)
+ : "1" (op1_32), "c" (count)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
result_32 = (op1_32 >> count);
+#endif
/* now write result back to destination */
if (i->modC0()) {
@@ -407,7 +422,9 @@
Write_RMW_virtual_dword(result_32);
}
+#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHR32);
+#endif
}
Index: cpu/string.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/string.cc,v
retrieving revision 1.17
diff -u -r1.17 string.cc
--- cpu/string.cc 30 Sep 2002 16:43:59 -0000 1.17
+++ cpu/string.cc 2 Oct 2002 00:34:45 -0000
@@ -993,9 +993,24 @@
read_virtual_byte(BX_SEG_REG_ES, di, &op2_8);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subb %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_8)
+ : "1" (op1_8), "g" (op2_8)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_8 = op1_8 - op2_8;
SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMPS8);
+#endif
if (BX_CPU_THIS_PTR get_DF ()) {
/* decrement ESI */
@@ -1168,9 +1183,24 @@
read_virtual_word(BX_SEG_REG_ES, edi, &op2_16);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMPS16);
+#endif
if (BX_CPU_THIS_PTR get_DF ()) {
/* decrement ESI */
@@ -1230,9 +1260,24 @@
read_virtual_word(BX_SEG_REG_ES, di, &op2_16);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMPS16);
+#endif
if (BX_CPU_THIS_PTR get_DF ()) {
/* decrement ESI */
@@ -1272,8 +1317,7 @@
diff_8 = op1_8 - op2_8;
SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SCAS8);
-
-
+
if (BX_CPU_THIS_PTR get_DF ()) {
/* decrement ESI */
rdi--;
@@ -1297,10 +1341,24 @@
read_virtual_byte(BX_SEG_REG_ES, edi, &op2_8);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subb %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_8)
+ : "1" (op1_8), "g" (op2_8)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_8 = op1_8 - op2_8;
SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SCAS8);
-
+#endif
if (BX_CPU_THIS_PTR get_DF ()) {
/* decrement ESI */
@@ -1327,9 +1385,24 @@
read_virtual_byte(BX_SEG_REG_ES, di, &op2_8);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subb %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_8)
+ : "1" (op1_8), "g" (op2_8)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_8 = op1_8 - op2_8;
SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SCAS8);
+#endif
if (BX_CPU_THIS_PTR get_DF ()) {
/* decrement ESI */
@@ -1469,9 +1542,24 @@
op1_16 = AX;
read_virtual_word(BX_SEG_REG_ES, edi, &op2_16);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SCAS16);
+#endif
if (BX_CPU_THIS_PTR get_DF ()) {
/* decrement ESI */
@@ -1522,9 +1610,24 @@
op1_16 = AX;
read_virtual_word(BX_SEG_REG_ES, di, &op2_16);
+#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
+ Bit32u flags32;
+ asm (
+ "subw %3, %1\n\t"
+ "pushfl \n\t"
+ "popl %0"
+ : "=g" (flags32), "=r" (diff_16)
+ : "1" (op1_16), "g" (op2_16)
+ : "cc"
+ );
+ BX_CPU_THIS_PTR eflags.val32 =
+ (BX_CPU_THIS_PTR eflags.val32 & ~EFlagsOSZAPCMask) | (flags32 & EFlagsOSZAPCMask);
+ BX_CPU_THIS_PTR lf_flags_status = 0;
+#else
diff_16 = op1_16 - op2_16;
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SCAS16);
+#endif
if (BX_CPU_THIS_PTR get_DF ()) {
/* decrement ESI */