Added ./configure option --enable-all-optimizations which turns on
all available optimizations in one shot. Finished one last case of an instruction which could but didn't use the Read-Modify-Write variants of access.cc functions. Started going through the integer instructions, merging obvious cases where there are two "if (modrm==11b) {" clauses and very little action in between, and cleaning up the aweful indentation leftover from many years ago when those instructions were implemented using cut-and-paste. We may get a little extra performance out of these mods, but they'll also be easier after I'm finished to enhance with asm() statements to knock out the lazy flags processing on x86.
This commit is contained in:
parent
81b1db7b47
commit
00c14e4efe
6297
bochs/configure
vendored
6297
bochs/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@ dnl // Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(bochs.h)
|
||||
AC_REVISION([[$Id: configure.in,v 1.135 2002-09-27 20:06:57 bdenney Exp $]])
|
||||
AC_REVISION([[$Id: configure.in,v 1.136 2002-09-30 02:02:05 kevinlawton Exp $]])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl // Put Bochs version information right here so that it gets substituted
|
||||
@ -605,14 +605,14 @@ AC_ARG_ENABLE(guest2host-tlb,
|
||||
[ --enable-guest2host-tlb support guest to host addr TLB for speed],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(BX_SupportGuest2HostTLB, 1)
|
||||
speedup_guest2host_tlb=1
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SupportGuest2HostTLB, 0)
|
||||
speedup_guest2host_tlb=0
|
||||
fi],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SupportGuest2HostTLB, 0)
|
||||
speedup_guest2host_tlb=0
|
||||
]
|
||||
)
|
||||
|
||||
@ -621,14 +621,14 @@ AC_ARG_ENABLE(repeat-speedups,
|
||||
[ --enable-repeat-speedups support repeated IO and mem copy speedups],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(BX_SupportRepeatSpeedups, 1)
|
||||
speedup_repeat=1
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SupportRepeatSpeedups, 0)
|
||||
speedup_repeat=0
|
||||
fi],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SupportRepeatSpeedups, 0)
|
||||
speedup_repeat=0
|
||||
]
|
||||
)
|
||||
|
||||
@ -637,14 +637,14 @@ AC_ARG_ENABLE(icache,
|
||||
[ --enable-icache support instruction cache (runs faster)],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(BX_SupportICache, 1)
|
||||
speedup_iCache=1
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SupportICache, 0)
|
||||
speedup_iCache=0
|
||||
fi],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SupportICache, 0)
|
||||
speedup_iCache=0
|
||||
]
|
||||
)
|
||||
|
||||
@ -675,14 +675,14 @@ AC_ARG_ENABLE(host-specific-asms,
|
||||
[ --enable-host-specific-asms support for host specific inline assembly],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(BX_SupportHostAsms, 1)
|
||||
speedup_host_specific_asms=1
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SupportHostAsms, 0)
|
||||
speedup_host_specific_asms=0
|
||||
fi],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(BX_SupportHostAsms, 1)
|
||||
speedup_host_specific_asms=1
|
||||
]
|
||||
)
|
||||
|
||||
@ -833,6 +833,62 @@ AC_ARG_ENABLE(disasm,
|
||||
)
|
||||
AC_SUBST(DISASM_VAR)
|
||||
|
||||
AC_MSG_CHECKING(for ALL optimizations enabled)
|
||||
AC_ARG_ENABLE(all-optimizations,
|
||||
[ --enable-all-optimizations compile in all possible optimizations],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
speedups_all=1
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
speedups_all=0
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
speedups_all=0
|
||||
]
|
||||
)
|
||||
|
||||
#
|
||||
# Optimizations section. Decide what the status of various optimizations
|
||||
# should be based on configure choices and other factors.
|
||||
#
|
||||
|
||||
if test "$speedups_all" = 1; then
|
||||
# Configure requested to force all options enabled.
|
||||
speedup_guest2host_tlb=1
|
||||
speedup_repeat=1
|
||||
speedup_iCache=1
|
||||
speedup_host_specific_asms=1
|
||||
fi
|
||||
|
||||
if test "$speedup_guest2host_tlb" = 1; then
|
||||
AC_DEFINE(BX_SupportGuest2HostTLB, 1)
|
||||
else
|
||||
AC_DEFINE(BX_SupportGuest2HostTLB, 0)
|
||||
fi
|
||||
|
||||
if test "$speedup_repeat" = 1; then
|
||||
AC_DEFINE(BX_SupportRepeatSpeedups, 1)
|
||||
else
|
||||
AC_DEFINE(BX_SupportRepeatSpeedups, 0)
|
||||
fi
|
||||
|
||||
if test "$speedup_iCache" = 1; then
|
||||
AC_DEFINE(BX_SupportICache, 1)
|
||||
else
|
||||
AC_DEFINE(BX_SupportICache, 0)
|
||||
fi
|
||||
|
||||
if test "$speedup_host_specific_asms" = 1; then
|
||||
AC_DEFINE(BX_SupportHostAsms, 1)
|
||||
else
|
||||
AC_DEFINE(BX_SupportHostAsms, 0)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
READLINE_LIB=""
|
||||
rl_without_curses_ok=no
|
||||
rl_with_curses_ok=no
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: arith16.cc,v 1.21 2002-09-29 19:21:36 kevinlawton Exp $
|
||||
// $Id: arith16.cc,v 1.22 2002-09-30 02:02:06 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -86,32 +86,22 @@ BX_CPU_C::DEC_RX(bxInstruction_c *i)
|
||||
void
|
||||
BX_CPU_C::ADD_EwGw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op2_16, op1_16, sum_16;
|
||||
Bit16u op2_16, op1_16, sum_16;
|
||||
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op2_16 is a register, RMAddr(i) is an index of a register */
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
sum_16 = op1_16 + op2_16;
|
||||
BX_WRITE_16BIT_REG(i->rm(), sum_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
sum_16 = op1_16 + op2_16;
|
||||
Write_RMW_virtual_word(sum_16);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), sum_16);
|
||||
}
|
||||
else {
|
||||
write_virtual_word(i->seg(), RMAddr(i), &sum_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +144,6 @@ BX_CPU_C::ADD_GwEGw(bxInstruction_c *i)
|
||||
Bit16u op1_16, op2_16, sum_16;
|
||||
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
|
||||
#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
|
||||
@ -185,18 +174,16 @@ BX_CPU_C::ADD_GwEGw(bxInstruction_c *i)
|
||||
void
|
||||
BX_CPU_C::ADD_AXIw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, op2_16, sum_16;
|
||||
Bit16u op1_16, op2_16, sum_16;
|
||||
|
||||
op1_16 = AX;
|
||||
op1_16 = AX;
|
||||
op2_16 = i->Iw();
|
||||
|
||||
op2_16 = i->Iw();
|
||||
sum_16 = op1_16 + op2_16;
|
||||
|
||||
sum_16 = op1_16 + op2_16;
|
||||
AX = sum_16;
|
||||
|
||||
/* now write sum back to destination */
|
||||
AX = sum_16;
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
|
||||
}
|
||||
|
||||
void
|
||||
@ -207,33 +194,21 @@ BX_CPU_C::ADC_EwGw(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
|
||||
|
||||
/* op2_16 is a register, RMAddr(i) is an index of a register */
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
sum_16 = op1_16 + op2_16 + temp_CF;
|
||||
BX_WRITE_16BIT_REG(i->rm(), sum_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
sum_16 = op1_16 + op2_16 + temp_CF;
|
||||
Write_RMW_virtual_word(sum_16);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), sum_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(sum_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -246,25 +221,21 @@ BX_CPU_C::ADC_GwEw(bxInstruction_c *i)
|
||||
temp_CF = getB_CF();
|
||||
|
||||
|
||||
/* op1_16 is a register, RMAddr(i) is an index of a register */
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op2_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
}
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
}
|
||||
|
||||
sum_16 = op1_16 + op2_16 + temp_CF;
|
||||
sum_16 = op1_16 + op2_16 + temp_CF;
|
||||
|
||||
/* now write sum back to destination */
|
||||
BX_WRITE_16BIT_REG(i->nnn(), sum_16);
|
||||
BX_WRITE_16BIT_REG(i->nnn(), sum_16);
|
||||
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -276,17 +247,15 @@ BX_CPU_C::ADC_AXIw(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
op1_16 = AX;
|
||||
op1_16 = AX;
|
||||
op2_16 = i->Iw();
|
||||
|
||||
op2_16 = i->Iw();
|
||||
sum_16 = op1_16 + op2_16 + temp_CF;
|
||||
|
||||
sum_16 = op1_16 + op2_16 + temp_CF;
|
||||
AX = sum_16;
|
||||
|
||||
/* now write sum back to destination */
|
||||
AX = sum_16;
|
||||
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -298,34 +267,23 @@ BX_CPU_C::SBB_EwGw(bxInstruction_c *i)
|
||||
Boolean temp_CF;
|
||||
Bit16u op2_16, op1_16, diff_16;
|
||||
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op2_16 is a register, RMAddr(i) is an index of a register */
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
diff_16 = op1_16 - (op2_16 + temp_CF);
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
diff_16 = op1_16 - (op2_16 + temp_CF);
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -336,29 +294,23 @@ BX_CPU_C::SBB_GwEw(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
Bit16u op1_16, op2_16, diff_16;
|
||||
|
||||
Bit16u op1_16, op2_16, diff_16;
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
}
|
||||
|
||||
/* op1_16 is a register, RMAddr(i) is an index of a register */
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
diff_16 = op1_16 - (op2_16 + temp_CF);
|
||||
|
||||
/* op2_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
}
|
||||
BX_WRITE_16BIT_REG(i->nnn(), diff_16);
|
||||
|
||||
diff_16 = op1_16 - (op2_16 + temp_CF);
|
||||
|
||||
/* now write diff back to destination */
|
||||
BX_WRITE_16BIT_REG(i->nnn(), diff_16);
|
||||
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -370,18 +322,15 @@ BX_CPU_C::SBB_AXIw(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
op1_16 = AX;
|
||||
op2_16 = i->Iw();
|
||||
|
||||
op1_16 = AX;
|
||||
diff_16 = op1_16 - (op2_16 + temp_CF);
|
||||
|
||||
op2_16 = i->Iw();
|
||||
AX = diff_16;
|
||||
|
||||
diff_16 = op1_16 - (op2_16 + temp_CF);
|
||||
|
||||
/* now write diff back to destination */
|
||||
AX = diff_16;
|
||||
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -394,109 +343,80 @@ BX_CPU_C::SBB_EwIw(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
op2_16 = i->Iw();
|
||||
|
||||
|
||||
|
||||
op2_16 = i->Iw();
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
diff_16 = op1_16 - (op2_16 + temp_CF);
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
diff_16 = op1_16 - (op2_16 + temp_CF);
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::SUB_EwGw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op2_16, op1_16, diff_16;
|
||||
Bit16u op2_16, op1_16, diff_16;
|
||||
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op2_16 is a register, RMAddr(i) is an index of a register */
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
diff_16 = op1_16 - op2_16;
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
diff_16 = op1_16 - op2_16;
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::SUB_GwEw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, op2_16, diff_16;
|
||||
Bit16u op1_16, op2_16, diff_16;
|
||||
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op1_16 is a register, RMAddr(i) is an index of a register */
|
||||
op1_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
}
|
||||
|
||||
/* op2_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
}
|
||||
diff_16 = op1_16 - op2_16;
|
||||
|
||||
diff_16 = op1_16 - op2_16;
|
||||
BX_WRITE_16BIT_REG(i->nnn(), diff_16);
|
||||
|
||||
/* now write diff back to destination */
|
||||
BX_WRITE_16BIT_REG(i->nnn(), diff_16);
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
}
|
||||
|
||||
void
|
||||
BX_CPU_C::SUB_AXIw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, op2_16, diff_16;
|
||||
Bit16u op1_16, op2_16, diff_16;
|
||||
|
||||
op1_16 = AX;
|
||||
op1_16 = AX;
|
||||
op2_16 = i->Iw();
|
||||
|
||||
op2_16 = i->Iw();
|
||||
diff_16 = op1_16 - op2_16;
|
||||
|
||||
diff_16 = op1_16 - op2_16;
|
||||
AX = diff_16;
|
||||
|
||||
|
||||
/* now write diff back to destination */
|
||||
AX = diff_16;
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
}
|
||||
|
||||
|
||||
@ -578,7 +498,6 @@ BX_CPU_C::CMP_AXIw(bxInstruction_c *i)
|
||||
Bit16u op1_16, op2_16;
|
||||
|
||||
op1_16 = AX;
|
||||
|
||||
op2_16 = i->Iw();
|
||||
|
||||
#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
|
||||
@ -616,12 +535,12 @@ BX_CPU_C::CWD(bxInstruction_c *i)
|
||||
{
|
||||
/* CWD: no flags are affected */
|
||||
|
||||
if (AX & 0x8000) {
|
||||
DX = 0xFFFF;
|
||||
}
|
||||
else {
|
||||
DX = 0x0000;
|
||||
}
|
||||
if (AX & 0x8000) {
|
||||
DX = 0xFFFF;
|
||||
}
|
||||
else {
|
||||
DX = 0x0000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -630,45 +549,35 @@ BX_CPU_C::XADD_EwGw(bxInstruction_c *i)
|
||||
{
|
||||
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
|
||||
|
||||
Bit16u op2_16, op1_16, sum_16;
|
||||
Bit16u op2_16, op1_16, sum_16;
|
||||
|
||||
/* XADD dst(r/m), src(r)
|
||||
* temp <-- src + dst | sum = op2 + op1
|
||||
* src <-- dst | op2 = op1
|
||||
* dst <-- tmp | op1 = sum
|
||||
*/
|
||||
/* XADD dst(r/m), src(r)
|
||||
* temp <-- src + dst | sum = op2 + op1
|
||||
* src <-- dst | op2 = op1
|
||||
* dst <-- tmp | op1 = sum
|
||||
*/
|
||||
|
||||
/* op2 is a register, RMAddr(i) is an index of a register */
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
sum_16 = op1_16 + op2_16;
|
||||
// and write destination into source
|
||||
// Note: if both op1 & op2 are registers, the last one written
|
||||
// should be the sum, as op1 & op2 may be the same register.
|
||||
// For example: XADD AL, AL
|
||||
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
|
||||
BX_WRITE_16BIT_REG(i->rm(), sum_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
sum_16 = op1_16 + op2_16;
|
||||
Write_RMW_virtual_word(sum_16);
|
||||
/* and write destination into source */
|
||||
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
// and write destination into source
|
||||
// Note: if both op1 & op2 are registers, the last one written
|
||||
// should be the sum, as op1 & op2 may be the same register.
|
||||
// For example: XADD AL, AL
|
||||
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
|
||||
BX_WRITE_16BIT_REG(i->rm(), sum_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(sum_16);
|
||||
/* and write destination into source */
|
||||
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
|
||||
}
|
||||
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_XADD16);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_XADD16);
|
||||
#else
|
||||
BX_PANIC(("XADD_EvGv: not supported on < 80486"));
|
||||
#endif
|
||||
@ -750,61 +659,44 @@ BX_CPU_C::ADC_EwIw(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
op2_16 = i->Iw();
|
||||
|
||||
op2_16 = i->Iw();
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
sum_16 = op1_16 + op2_16 + temp_CF;
|
||||
BX_WRITE_16BIT_REG(i->rm(), sum_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
sum_16 = op1_16 + op2_16 + temp_CF;
|
||||
Write_RMW_virtual_word(sum_16);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), sum_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(sum_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::SUB_EwIw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op2_16, op1_16, diff_16;
|
||||
Bit16u op2_16, op1_16, diff_16;
|
||||
|
||||
|
||||
op2_16 = i->Iw();
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
op2_16 = i->Iw();
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
diff_16 = op1_16 - op2_16;
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
diff_16 = op1_16 - op2_16;
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
|
||||
}
|
||||
|
||||
void
|
||||
@ -847,85 +739,61 @@ BX_CPU_C::CMP_EwIw(bxInstruction_c *i)
|
||||
void
|
||||
BX_CPU_C::NEG_Ew(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16, diff_16;
|
||||
Bit16u op1_16, diff_16;
|
||||
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
diff_16 = 0 - op1_16;
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
diff_16 = 0 - op1_16;
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), diff_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(diff_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_16(op1_16, 0, diff_16, BX_INSTR_NEG16);
|
||||
SET_FLAGS_OSZAPC_16(op1_16, 0, diff_16, BX_INSTR_NEG16);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::INC_Ew(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16;
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
Bit16u op1_16;
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
op1_16++;
|
||||
BX_WRITE_16BIT_REG(i->rm(), op1_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
op1_16++;
|
||||
Write_RMW_virtual_word(op1_16);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), op1_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(op1_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_INC16);
|
||||
SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_INC16);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::DEC_Ew(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op1_16;
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
Bit16u op1_16;
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
op1_16--;
|
||||
BX_WRITE_16BIT_REG(i->rm(), op1_16);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
op1_16--;
|
||||
Write_RMW_virtual_word(op1_16);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), op1_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(op1_16);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_DEC16);
|
||||
SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_DEC16);
|
||||
}
|
||||
|
||||
|
||||
@ -934,40 +802,38 @@ BX_CPU_C::CMPXCHG_EwGw(bxInstruction_c *i)
|
||||
{
|
||||
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
|
||||
|
||||
Bit16u op2_16, op1_16, diff_16;
|
||||
Bit16u op2_16, op1_16, diff_16;
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
diff_16 = AX - op1_16;
|
||||
|
||||
SET_FLAGS_OSZAPC_16(AX, op1_16, diff_16, BX_INSTR_CMP16);
|
||||
|
||||
if (diff_16 == 0) { // if accumulator == dest
|
||||
// ZF = 1
|
||||
set_ZF(1);
|
||||
// dest <-- src
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
/* op1_16 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_16 = BX_READ_16BIT_REG(i->rm());
|
||||
BX_WRITE_16BIT_REG(i->rm(), op2_16);
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_word(i->seg(), RMAddr(i), &op1_16);
|
||||
}
|
||||
|
||||
diff_16 = AX - op1_16;
|
||||
|
||||
SET_FLAGS_OSZAPC_16(AX, op1_16, diff_16, BX_INSTR_CMP16);
|
||||
|
||||
if (diff_16 == 0) { // if accumulator == dest
|
||||
// ZF = 1
|
||||
set_ZF(1);
|
||||
// dest <-- src
|
||||
op2_16 = BX_READ_16BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), op2_16);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_word(op2_16);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ZF = 0
|
||||
set_ZF(0);
|
||||
// accumulator <-- dest
|
||||
AX = op1_16;
|
||||
Write_RMW_virtual_word(op2_16);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ZF = 0
|
||||
set_ZF(0);
|
||||
// accumulator <-- dest
|
||||
AX = op1_16;
|
||||
}
|
||||
|
||||
#else
|
||||
BX_PANIC(("CMPXCHG_EwGw:"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: arith32.cc,v 1.23 2002-09-29 19:21:36 kevinlawton Exp $
|
||||
// $Id: arith32.cc,v 1.24 2002-09-30 02:02:06 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -108,32 +108,22 @@ BX_CPU_C::DEC_ERX(bxInstruction_c *i)
|
||||
void
|
||||
BX_CPU_C::ADD_EdGd(bxInstruction_c *i)
|
||||
{
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
|
||||
/* op2_32 is a register, RMAddr(i) is an index of a register */
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
sum_32 = op1_32 + op2_32;
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), sum_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
sum_32 = op1_32 + op2_32;
|
||||
Write_RMW_virtual_dword(sum_32);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), sum_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(sum_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
|
||||
}
|
||||
|
||||
|
||||
@ -163,7 +153,6 @@ BX_CPU_C::ADD_GdEEd(bxInstruction_c *i)
|
||||
sum_32 = op1_32 + op2_32;
|
||||
#endif
|
||||
|
||||
/* now write sum back to destination */
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), sum_32);
|
||||
|
||||
#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
|
||||
@ -177,7 +166,6 @@ BX_CPU_C::ADD_GdEGd(bxInstruction_c *i)
|
||||
Bit32u op1_32, op2_32, sum_32;
|
||||
|
||||
op1_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
|
||||
#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
|
||||
@ -197,7 +185,6 @@ BX_CPU_C::ADD_GdEGd(bxInstruction_c *i)
|
||||
sum_32 = op1_32 + op2_32;
|
||||
#endif
|
||||
|
||||
/* now write sum back to destination */
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), sum_32);
|
||||
|
||||
#if !(defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
|
||||
@ -209,19 +196,16 @@ BX_CPU_C::ADD_GdEGd(bxInstruction_c *i)
|
||||
void
|
||||
BX_CPU_C::ADD_EAXId(bxInstruction_c *i)
|
||||
{
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op1_32, op2_32, sum_32;
|
||||
Bit32u op1_32, op2_32, sum_32;
|
||||
|
||||
op1_32 = EAX;
|
||||
op1_32 = EAX;
|
||||
op2_32 = i->Id();
|
||||
|
||||
op2_32 = i->Id();
|
||||
sum_32 = op1_32 + op2_32;
|
||||
|
||||
sum_32 = op1_32 + op2_32;
|
||||
RAX = sum_32;
|
||||
|
||||
/* now write sum back to destination */
|
||||
RAX = sum_32;
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
|
||||
}
|
||||
|
||||
void
|
||||
@ -231,34 +215,23 @@ BX_CPU_C::ADC_EdGd(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
|
||||
/* op2_32 is a register, RMAddr(i) is an index of a register */
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
sum_32 = op1_32 + op2_32 + temp_CF;
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), sum_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
sum_32 = op1_32 + op2_32 + temp_CF;
|
||||
Write_RMW_virtual_dword(sum_32);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), sum_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(sum_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -269,29 +242,23 @@ BX_CPU_C::ADC_GdEd(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
Bit32u op1_32, op2_32, sum_32;
|
||||
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op1_32, op2_32, sum_32;
|
||||
op1_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op1_32 is a register, RMAddr(i) is an index of a register */
|
||||
op1_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
if (i->modC0()) {
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
|
||||
}
|
||||
|
||||
/* op2_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
|
||||
}
|
||||
sum_32 = op1_32 + op2_32 + temp_CF;
|
||||
|
||||
sum_32 = op1_32 + op2_32 + temp_CF;
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), sum_32);
|
||||
|
||||
/* now write sum back to destination */
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), sum_32);
|
||||
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -302,20 +269,17 @@ BX_CPU_C::ADC_EAXId(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op1_32, op2_32, sum_32;
|
||||
Bit32u op1_32, op2_32, sum_32;
|
||||
|
||||
op1_32 = EAX;
|
||||
op1_32 = EAX;
|
||||
op2_32 = i->Id();
|
||||
|
||||
op2_32 = i->Id();
|
||||
sum_32 = op1_32 + op2_32 + temp_CF;
|
||||
|
||||
sum_32 = op1_32 + op2_32 + temp_CF;
|
||||
RAX = sum_32;
|
||||
|
||||
/* now write sum back to destination */
|
||||
RAX = sum_32;
|
||||
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -328,34 +292,23 @@ BX_CPU_C::SBB_EdGd(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
|
||||
/* op2_32 is a register, RMAddr(i) is an index of a register */
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
diff_32 = op1_32 - (op2_32 + temp_CF);
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
diff_32 = op1_32 - (op2_32 + temp_CF);
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -366,29 +319,23 @@ BX_CPU_C::SBB_GdEd(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
Bit32u op1_32, op2_32, diff_32;
|
||||
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op1_32, op2_32, diff_32;
|
||||
op1_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op1_32 is a register, RMAddr(i) is an index of a register */
|
||||
op1_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
if (i->modC0()) {
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
|
||||
}
|
||||
|
||||
/* op2_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
|
||||
}
|
||||
diff_32 = op1_32 - (op2_32 + temp_CF);
|
||||
|
||||
diff_32 = op1_32 - (op2_32 + temp_CF);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), diff_32);
|
||||
|
||||
/* now write diff back to destination */
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), diff_32);
|
||||
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -399,20 +346,17 @@ BX_CPU_C::SBB_EAXId(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op1_32, op2_32, diff_32;
|
||||
Bit32u op1_32, op2_32, diff_32;
|
||||
|
||||
op1_32 = EAX;
|
||||
op1_32 = EAX;
|
||||
op2_32 = i->Id();
|
||||
|
||||
op2_32 = i->Id();
|
||||
diff_32 = op1_32 - (op2_32 + temp_CF);
|
||||
|
||||
diff_32 = op1_32 - (op2_32 + temp_CF);
|
||||
RAX = diff_32;
|
||||
|
||||
/* now write diff back to destination */
|
||||
RAX = diff_32;
|
||||
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
@ -424,110 +368,82 @@ BX_CPU_C::SBB_EdId(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
|
||||
op2_32 = i->Id();
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
op2_32 = i->Id();
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
diff_32 = op1_32 - (op2_32 + temp_CF);
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
diff_32 = op1_32 - (op2_32 + temp_CF);
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::SUB_EdGd(bxInstruction_c *i)
|
||||
{
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
|
||||
/* op2_32 is a register, RMAddr(i) is an index of a register */
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
diff_32 = op1_32 - op2_32;
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
diff_32 = op1_32 - op2_32;
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::SUB_GdEd(bxInstruction_c *i)
|
||||
{
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op1_32, op2_32, diff_32;
|
||||
Bit32u op1_32, op2_32, diff_32;
|
||||
|
||||
/* op1_32 is a register, RMAddr(i) is an index of a register */
|
||||
op1_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
op1_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op2_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
|
||||
}
|
||||
if (i->modC0()) {
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
|
||||
}
|
||||
|
||||
diff_32 = op1_32 - op2_32;
|
||||
diff_32 = op1_32 - op2_32;
|
||||
|
||||
/* now write diff back to destination */
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), diff_32);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), diff_32);
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
|
||||
}
|
||||
|
||||
void
|
||||
BX_CPU_C::SUB_EAXId(bxInstruction_c *i)
|
||||
{
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op1_32, op2_32, diff_32;
|
||||
Bit32u op1_32, op2_32, diff_32;
|
||||
|
||||
op1_32 = EAX;
|
||||
op1_32 = EAX;
|
||||
op2_32 = i->Id();
|
||||
|
||||
op2_32 = i->Id();
|
||||
diff_32 = op1_32 - op2_32;
|
||||
|
||||
diff_32 = op1_32 - op2_32;
|
||||
RAX = diff_32;
|
||||
|
||||
/* now write diff back to destination */
|
||||
RAX = diff_32;
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
|
||||
}
|
||||
|
||||
|
||||
@ -609,7 +525,6 @@ BX_CPU_C::CMP_EAXId(bxInstruction_c *i)
|
||||
Bit32u op1_32, op2_32;
|
||||
|
||||
op1_32 = EAX;
|
||||
|
||||
op2_32 = i->Id();
|
||||
|
||||
#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
|
||||
@ -638,10 +553,10 @@ BX_CPU_C::CMP_EAXId(bxInstruction_c *i)
|
||||
BX_CPU_C::CWDE(bxInstruction_c *i)
|
||||
{
|
||||
/* CBW: no flags are effected */
|
||||
Bit32u temp;
|
||||
Bit32u temp;
|
||||
|
||||
temp = (Bit16s) AX;
|
||||
RAX = temp;
|
||||
temp = (Bit16s) AX;
|
||||
RAX = temp;
|
||||
}
|
||||
|
||||
void
|
||||
@ -649,12 +564,12 @@ BX_CPU_C::CDQ(bxInstruction_c *i)
|
||||
{
|
||||
/* CDQ: no flags are affected */
|
||||
|
||||
if (EAX & 0x80000000) {
|
||||
RDX = 0xFFFFFFFF;
|
||||
}
|
||||
else {
|
||||
RDX = 0x00000000;
|
||||
}
|
||||
if (EAX & 0x80000000) {
|
||||
RDX = 0xFFFFFFFF;
|
||||
}
|
||||
else {
|
||||
RDX = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
// Some info on the opcodes at {0F,A6} and {0F,A7}
|
||||
@ -690,47 +605,37 @@ BX_CPU_C::XADD_EdGd(bxInstruction_c *i)
|
||||
{
|
||||
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
|
||||
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
|
||||
/* XADD dst(r/m), src(r)
|
||||
* temp <-- src + dst | sum = op2 + op1
|
||||
* src <-- dst | op2 = op1
|
||||
* dst <-- tmp | op1 = sum
|
||||
*/
|
||||
/* XADD dst(r/m), src(r)
|
||||
* temp <-- src + dst | sum = op2 + op1
|
||||
* src <-- dst | op2 = op1
|
||||
* dst <-- tmp | op1 = sum
|
||||
*/
|
||||
|
||||
/* op2 is a register, RMAddr(i) is an index of a register */
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
sum_32 = op1_32 + op2_32;
|
||||
// and write destination into source
|
||||
// Note: if both op1 & op2 are registers, the last one written
|
||||
// should be the sum, as op1 & op2 may be the same register.
|
||||
// For example: XADD AL, AL
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), sum_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
sum_32 = op1_32 + op2_32;
|
||||
Write_RMW_virtual_dword(sum_32);
|
||||
/* and write destination into source */
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
// and write destination into source
|
||||
// Note: if both op1 & op2 are registers, the last one written
|
||||
// should be the sum, as op1 & op2 may be the same register.
|
||||
// For example: XADD AL, AL
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), sum_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(sum_32);
|
||||
/* and write destination into source */
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
|
||||
}
|
||||
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_XADD32);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_XADD32);
|
||||
#else
|
||||
|
||||
#panic "XADD_EdGd"
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -776,7 +681,6 @@ BX_CPU_C::ADD_EGdId(bxInstruction_c *i)
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
|
||||
op2_32 = i->Id();
|
||||
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
|
||||
#if (defined(__i386__) && defined(__GNUC__) && BX_SupportHostAsms)
|
||||
@ -811,63 +715,45 @@ BX_CPU_C::ADC_EdId(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
Bit32u op2_32, op1_32, sum_32;
|
||||
|
||||
op2_32 = i->Id();
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
op2_32 = i->Id();
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
sum_32 = op1_32 + op2_32 + temp_CF;
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), sum_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
sum_32 = op1_32 + op2_32 + temp_CF;
|
||||
Write_RMW_virtual_dword(sum_32);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), sum_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(sum_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
|
||||
temp_CF);
|
||||
SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
|
||||
temp_CF);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::SUB_EdId(bxInstruction_c *i)
|
||||
{
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
|
||||
op2_32 = i->Id();
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
op2_32 = i->Id();
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
diff_32 = op1_32 - op2_32;
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
diff_32 = op1_32 - op2_32;
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
|
||||
}
|
||||
|
||||
void
|
||||
@ -911,85 +797,60 @@ BX_CPU_C::CMP_EdId(bxInstruction_c *i)
|
||||
void
|
||||
BX_CPU_C::NEG_Ed(bxInstruction_c *i)
|
||||
{
|
||||
/* for 32 bit operand size mode */
|
||||
Bit32u op1_32, diff_32;
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
Bit32u op1_32, diff_32;
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
diff_32 = 0 - op1_32;
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
diff_32 = 0 - op1_32;
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), diff_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(diff_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAPC_32(op1_32, 0, diff_32, BX_INSTR_NEG32);
|
||||
SET_FLAGS_OSZAPC_32(op1_32, 0, diff_32, BX_INSTR_NEG32);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::INC_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32;
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
Bit32u op1_32;
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
op1_32++;
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), op1_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
op1_32++;
|
||||
Write_RMW_virtual_dword(op1_32);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), op1_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(op1_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAP_32(0, 0, op1_32, BX_INSTR_INC32);
|
||||
SET_FLAGS_OSZAP_32(0, 0, op1_32, BX_INSTR_INC32);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::DEC_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op1_32;
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
Bit32u op1_32;
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
op1_32--;
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), op1_32);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
op1_32--;
|
||||
Write_RMW_virtual_dword(op1_32);
|
||||
}
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), op1_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(op1_32);
|
||||
}
|
||||
|
||||
SET_FLAGS_OSZAP_32(0, 0, op1_32, BX_INSTR_DEC32);
|
||||
SET_FLAGS_OSZAP_32(0, 0, op1_32, BX_INSTR_DEC32);
|
||||
}
|
||||
|
||||
|
||||
@ -998,40 +859,38 @@ BX_CPU_C::CMPXCHG_EdGd(bxInstruction_c *i)
|
||||
{
|
||||
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
|
||||
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
Bit32u op2_32, op1_32, diff_32;
|
||||
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
|
||||
diff_32 = EAX - op1_32;
|
||||
|
||||
SET_FLAGS_OSZAPC_32(EAX, op1_32, diff_32, BX_INSTR_CMP32);
|
||||
|
||||
if (diff_32 == 0) { // if accumulator == dest
|
||||
// ZF = 1
|
||||
set_ZF(1);
|
||||
// dest <-- src
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
/* op1_32 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_32 = BX_READ_32BIT_REG(i->rm());
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), op2_32);
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
|
||||
}
|
||||
|
||||
diff_32 = EAX - op1_32;
|
||||
|
||||
SET_FLAGS_OSZAPC_32(EAX, op1_32, diff_32, BX_INSTR_CMP32);
|
||||
|
||||
if (diff_32 == 0) { // if accumulator == dest
|
||||
// ZF = 1
|
||||
set_ZF(1);
|
||||
// dest <-- src
|
||||
op2_32 = BX_READ_32BIT_REG(i->nnn());
|
||||
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), op2_32);
|
||||
}
|
||||
else {
|
||||
Write_RMW_virtual_dword(op2_32);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ZF = 0
|
||||
set_ZF(0);
|
||||
// accumulator <-- dest
|
||||
RAX = op1_32;
|
||||
Write_RMW_virtual_dword(op2_32);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ZF = 0
|
||||
set_ZF(0);
|
||||
// accumulator <-- dest
|
||||
RAX = op1_32;
|
||||
}
|
||||
#else
|
||||
BX_PANIC(("CMPXCHG_EdGd:"));
|
||||
#endif
|
||||
@ -1042,36 +901,35 @@ BX_CPU_C::CMPXCHG8B(bxInstruction_c *i)
|
||||
{
|
||||
#if (BX_CPU_LEVEL >= 5) || (BX_CPU_LEVEL_HACKED >= 5)
|
||||
|
||||
Bit32u op1_64_lo, op1_64_hi, diff;
|
||||
Bit32u op1_64_lo, op1_64_hi, diff;
|
||||
|
||||
if (i->modC0()) {
|
||||
BX_INFO(("CMPXCHG8B: dest is reg: #UD"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
if (i->modC0()) {
|
||||
BX_INFO(("CMPXCHG8B: dest is reg: #UD"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op1_64_lo);
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i) + 4, &op1_64_hi);
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op1_64_lo);
|
||||
read_RMW_virtual_dword(i->seg(), RMAddr(i) + 4, &op1_64_hi);
|
||||
|
||||
diff = EAX - op1_64_lo;
|
||||
diff |= EDX - op1_64_hi;
|
||||
diff = EAX - op1_64_lo;
|
||||
diff |= EDX - op1_64_hi;
|
||||
|
||||
// SET_FLAGS_OSZAPC_32(EAX, op1_32, diff_32, BX_INSTR_CMP32);
|
||||
|
||||
if (diff == 0) { // if accumulator == dest
|
||||
// ZF = 1
|
||||
set_ZF(1);
|
||||
// dest <-- src
|
||||
Write_RMW_virtual_dword(ECX);
|
||||
write_virtual_dword(i->seg(), RMAddr(i), &EBX);
|
||||
}
|
||||
else {
|
||||
// ZF = 0
|
||||
set_ZF(0);
|
||||
// accumulator <-- dest
|
||||
RAX = op1_64_lo;
|
||||
RDX = op1_64_hi;
|
||||
}
|
||||
if (diff == 0) { // if accumulator == dest
|
||||
// ZF = 1
|
||||
set_ZF(1);
|
||||
// dest <-- src
|
||||
Write_RMW_virtual_dword(ECX);
|
||||
write_virtual_dword(i->seg(), RMAddr(i), &EBX);
|
||||
}
|
||||
else {
|
||||
// ZF = 0
|
||||
set_ZF(0);
|
||||
// accumulator <-- dest
|
||||
RAX = op1_64_lo;
|
||||
RDX = op1_64_hi;
|
||||
}
|
||||
|
||||
#else
|
||||
BX_INFO(("CMPXCHG8B: not implemented yet"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: arith8.cc,v 1.18 2002-09-28 01:16:09 kevinlawton Exp $
|
||||
// $Id: arith8.cc,v 1.19 2002-09-30 02:02:06 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -41,24 +41,16 @@ BX_CPU_C::ADD_EbGb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op2, op1, sum;
|
||||
|
||||
/* op2 is a register, RMAddr(i) is an index of a register */
|
||||
op2 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
}
|
||||
|
||||
sum = op1 + op2;
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
sum = op1 + op2;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), sum);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
sum = op1 + op2;
|
||||
Write_RMW_virtual_byte(sum);
|
||||
}
|
||||
|
||||
@ -72,22 +64,17 @@ BX_CPU_C::ADD_GbEb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1, op2, sum;
|
||||
|
||||
|
||||
/* op1 is a register, RMAddr(i) is an index of a register */
|
||||
op1 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op2 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
sum = op1 + op2;
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_byte(i->seg(), RMAddr(i), &op2);
|
||||
sum = op1 + op2;
|
||||
}
|
||||
|
||||
sum = op1 + op2;
|
||||
|
||||
/* now write sum back to destination, which is a register */
|
||||
BX_WRITE_8BIT_REGx(i->nnn(), i->extend8bitL(), sum);
|
||||
|
||||
SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
|
||||
@ -101,12 +88,10 @@ BX_CPU_C::ADD_ALIb(bxInstruction_c *i)
|
||||
|
||||
|
||||
op1 = AL;
|
||||
|
||||
op2 = i->Ib();
|
||||
|
||||
sum = op1 + op2;
|
||||
|
||||
/* now write sum back to destination, which is a register */
|
||||
AL = sum;
|
||||
|
||||
SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
|
||||
@ -121,27 +106,16 @@ BX_CPU_C::ADC_EbGb(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
|
||||
/* op2 is a register, RMAddr(i) is an index of a register */
|
||||
op2 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
}
|
||||
|
||||
sum = op1 + op2 + temp_CF;
|
||||
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
sum = op1 + op2 + temp_CF;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), sum);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
sum = op1 + op2 + temp_CF;
|
||||
Write_RMW_virtual_byte(sum);
|
||||
}
|
||||
|
||||
@ -157,16 +131,12 @@ BX_CPU_C::ADC_GbEb(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
|
||||
/* op1 is a register, RMAddr(i) is an index of a register */
|
||||
op1 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op2 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_byte(i->seg(), RMAddr(i), &op2);
|
||||
}
|
||||
|
||||
@ -175,7 +145,6 @@ BX_CPU_C::ADC_GbEb(bxInstruction_c *i)
|
||||
SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
|
||||
temp_CF);
|
||||
|
||||
/* now write sum back to destination, which is a register */
|
||||
BX_WRITE_8BIT_REGx(i->nnn(), i->extend8bitL(), sum);
|
||||
}
|
||||
|
||||
@ -190,12 +159,10 @@ BX_CPU_C::ADC_ALIb(bxInstruction_c *i)
|
||||
|
||||
|
||||
op1 = AL;
|
||||
|
||||
op2 = i->Ib();
|
||||
|
||||
sum = op1 + op2 + temp_CF;
|
||||
|
||||
/* now write sum back to destination, which is a register */
|
||||
AL = sum;
|
||||
|
||||
SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
|
||||
@ -212,25 +179,16 @@ BX_CPU_C::SBB_EbGb(bxInstruction_c *i)
|
||||
temp_CF = getB_CF();
|
||||
|
||||
|
||||
/* op2 is a register, RMAddr(i) is an index of a register */
|
||||
op2_8 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op1_8 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
}
|
||||
|
||||
diff_8 = op1_8 - (op2_8 + temp_CF);
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
diff_8 = op1_8 - (op2_8 + temp_CF);
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), diff_8);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
diff_8 = op1_8 - (op2_8 + temp_CF);
|
||||
Write_RMW_virtual_byte(diff_8);
|
||||
}
|
||||
|
||||
@ -247,22 +205,17 @@ BX_CPU_C::SBB_GbEb(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
|
||||
/* op1 is a register, RMAddr(i) is an index of a register */
|
||||
op1_8 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op2 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_byte(i->seg(), RMAddr(i), &op2_8);
|
||||
}
|
||||
|
||||
diff_8 = op1_8 - (op2_8 + temp_CF);
|
||||
|
||||
/* now write diff back to destination, which is a register */
|
||||
BX_WRITE_8BIT_REGx(i->nnn(), i->extend8bitL(), diff_8);
|
||||
|
||||
SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
|
||||
@ -278,14 +231,11 @@ BX_CPU_C::SBB_ALIb(bxInstruction_c *i)
|
||||
|
||||
temp_CF = getB_CF();
|
||||
|
||||
|
||||
op1_8 = AL;
|
||||
|
||||
op2_8 = i->Ib();
|
||||
|
||||
diff_8 = op1_8 - (op2_8 + temp_CF);
|
||||
|
||||
/* now write diff back to destination, which is a register */
|
||||
AL = diff_8;
|
||||
|
||||
SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
|
||||
@ -303,22 +253,14 @@ BX_CPU_C::SBB_EbIb(bxInstruction_c *i)
|
||||
|
||||
op2_8 = i->Ib();
|
||||
|
||||
/* op1_8 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
}
|
||||
|
||||
diff_8 = op1_8 - (op2_8 + temp_CF);
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
diff_8 = op1_8 - (op2_8 + temp_CF);
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), diff_8);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
diff_8 = op1_8 - (op2_8 + temp_CF);
|
||||
Write_RMW_virtual_byte(diff_8);
|
||||
}
|
||||
|
||||
@ -333,26 +275,16 @@ BX_CPU_C::SUB_EbGb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op2_8, op1_8, diff_8;
|
||||
|
||||
|
||||
/* op2 is a register, RMAddr(i) is an index of a register */
|
||||
op2_8 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op1_8 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
}
|
||||
|
||||
diff_8 = op1_8 - op2_8;
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
diff_8 = op1_8 - op2_8;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), diff_8);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
diff_8 = op1_8 - op2_8;
|
||||
Write_RMW_virtual_byte(diff_8);
|
||||
}
|
||||
|
||||
@ -365,22 +297,17 @@ BX_CPU_C::SUB_GbEb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1_8, op2_8, diff_8;
|
||||
|
||||
|
||||
/* op1 is a register, RMAddr(i) is an index of a register */
|
||||
op1_8 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op2 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op2_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_byte(i->seg(), RMAddr(i), &op2_8);
|
||||
}
|
||||
|
||||
diff_8 = op1_8 - op2_8;
|
||||
|
||||
/* now write diff back to destination, which is a register */
|
||||
BX_WRITE_8BIT_REGx(i->nnn(), i->extend8bitL(), diff_8);
|
||||
|
||||
SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
|
||||
@ -393,12 +320,10 @@ BX_CPU_C::SUB_ALIb(bxInstruction_c *i)
|
||||
Bit8u op1_8, op2_8, diff_8;
|
||||
|
||||
op1_8 = AL;
|
||||
|
||||
op2_8 = i->Ib();
|
||||
|
||||
diff_8 = op1_8 - op2_8;
|
||||
|
||||
/* now write diff back to destination, which is a register */
|
||||
AL = diff_8;
|
||||
|
||||
SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
|
||||
@ -523,22 +448,11 @@ BX_CPU_C::XADD_EbGb(bxInstruction_c *i)
|
||||
* dst <-- tmp | op1 = sum
|
||||
*/
|
||||
|
||||
/* op2 is a register, RMAddr(i) is an index of a register */
|
||||
op2 = BX_READ_8BIT_REGx(i->nnn(),i->extend8bitL());
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
}
|
||||
|
||||
sum = op1 + op2;
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
sum = op1 + op2;
|
||||
// and write destination into source
|
||||
// Note: if both op1 & op2 are registers, the last one written
|
||||
// should be the sum, as op1 & op2 may be the same register.
|
||||
@ -547,12 +461,13 @@ BX_CPU_C::XADD_EbGb(bxInstruction_c *i)
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), sum);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
sum = op1 + op2;
|
||||
Write_RMW_virtual_byte(sum);
|
||||
/* and write destination into source */
|
||||
BX_WRITE_8BIT_REGx(i->nnn(), i->extend8bitL(), op1);
|
||||
}
|
||||
|
||||
|
||||
SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_XADD8);
|
||||
#else
|
||||
BX_PANIC(("XADD_EbGb: not supported on < 80486"));
|
||||
@ -565,25 +480,16 @@ BX_CPU_C::ADD_EbIb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op2, op1, sum;
|
||||
|
||||
|
||||
op2 = i->Ib();
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
}
|
||||
|
||||
sum = op1 + op2;
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
sum = op1 + op2;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), sum);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
sum = op1 + op2;
|
||||
Write_RMW_virtual_byte(sum);
|
||||
}
|
||||
|
||||
@ -600,22 +506,14 @@ BX_CPU_C::ADC_EbIb(bxInstruction_c *i)
|
||||
|
||||
op2 = i->Ib();
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
}
|
||||
|
||||
sum = op1 + op2 + temp_CF;
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
sum = op1 + op2 + temp_CF;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), sum);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
sum = op1 + op2 + temp_CF;
|
||||
Write_RMW_virtual_byte(sum);
|
||||
}
|
||||
|
||||
@ -629,25 +527,16 @@ BX_CPU_C::SUB_EbIb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op2_8, op1_8, diff_8;
|
||||
|
||||
|
||||
op2_8 = i->Ib();
|
||||
|
||||
/* op1_8 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
}
|
||||
|
||||
diff_8 = op1_8 - op2_8;
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
diff_8 = op1_8 - op2_8;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), diff_8);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
diff_8 = op1_8 - op2_8;
|
||||
Write_RMW_virtual_byte(diff_8);
|
||||
}
|
||||
|
||||
@ -695,22 +584,14 @@ BX_CPU_C::NEG_Eb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1_8, diff_8;
|
||||
|
||||
/* op1_8 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
}
|
||||
|
||||
diff_8 = 0 - op1_8;
|
||||
|
||||
/* now write diff back to destination */
|
||||
if (i->modC0()) {
|
||||
diff_8 = 0 - op1_8;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), diff_8);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
diff_8 = 0 - op1_8;
|
||||
Write_RMW_virtual_byte(diff_8);
|
||||
}
|
||||
|
||||
@ -723,23 +604,14 @@ BX_CPU_C::INC_Eb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1;
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
}
|
||||
|
||||
|
||||
op1++;
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
op1++;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), op1);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1);
|
||||
op1++;
|
||||
Write_RMW_virtual_byte(op1);
|
||||
}
|
||||
|
||||
@ -752,22 +624,14 @@ BX_CPU_C::DEC_Eb(bxInstruction_c *i)
|
||||
{
|
||||
Bit8u op1_8;
|
||||
|
||||
/* op1_8 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
}
|
||||
|
||||
op1_8--;
|
||||
|
||||
/* now write sum back to destination */
|
||||
if (i->modC0()) {
|
||||
op1_8--;
|
||||
BX_WRITE_8BIT_REGx(i->rm(), i->extend8bitL(), op1_8);
|
||||
}
|
||||
else {
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
op1_8--;
|
||||
Write_RMW_virtual_byte(op1_8);
|
||||
}
|
||||
|
||||
@ -782,12 +646,10 @@ BX_CPU_C::CMPXCHG_EbGb(bxInstruction_c *i)
|
||||
Bit8u op2_8, op1_8, diff_8;
|
||||
|
||||
|
||||
/* op1_8 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
op1_8 = BX_READ_8BIT_REGx(i->rm(),i->extend8bitL());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_RMW_virtual_byte(i->seg(), RMAddr(i), &op1_8);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user