Commented problematic check in misc_mem.cc

Implemnted lazy-flags and undocumented flags handling for IMUL instructions
This commit is contained in:
Stanislav Shwartsman 2004-08-30 21:47:24 +00:00
parent 14d5b69d96
commit 016207b222
9 changed files with 216 additions and 191 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.173 2004-08-18 20:47:35 sshwarts Exp $
// $Id: cpu.h,v 1.174 2004-08-30 21:47:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -3357,7 +3357,6 @@ typedef enum _show_flags {
BX_CPU_THIS_PTR eflags.val32 &= ~((1<<11) | (1<<0)); \
BX_CPU_THIS_PTR eflags.val32 |= ((!!new_of)<<11) | ((!!new_cf)<<0); \
BX_CPU_THIS_PTR lf_flags_status &= 0x0ffff0; \
/* could also mark other bits undefined here ? */ \
}
#endif // #ifndef BX_CPU_H

View File

@ -122,7 +122,7 @@ static Bit32u get_std_cpuid_features()
{
Bit32u features = 0; // start with none
// EAX: CPU Version Infromation
// EAX: CPU Version Information
// [3:0] Stepping ID
// [7:4] Model: starts at 1
// [11:8] Family: 4=486, 5=Pentium, 6=PPro, ...
@ -285,8 +285,8 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
// [22:22] AMD MMX Extensions
// [25:28] Reserved
// [29:29] Long Mode
// [30:30] AMD 3DNow Extensions
// [31:31] AMD 3DNow Intructions
// [30:30] AMD 3DNow! Extensions
// [31:31] AMD 3DNow! Instructions
features = features & 0x0183F3FF;
RDX = features | (1 << 29) | (1 << 11);
RBX = 0;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: lazy_flags.cc,v 1.24 2004-08-27 18:43:23 sshwarts Exp $
// $Id: lazy_flags.cc,v 1.25 2004-08-30 21:47:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -31,7 +31,6 @@
#include "bochs.h"
#define LOG_THIS BX_CPU_THIS_PTR
bx_bool BX_CPU_C::get_CFLazy(void)
{
unsigned cf;
@ -228,17 +227,46 @@ bx_bool BX_CPU_C::get_CFLazy(void)
(64 - BX_CPU_THIS_PTR oszapc.op2_64)) & 0x01;
break;
#endif
case BX_INSTR_MUL8:
case BX_INSTR_IMUL_AL:
cf = ! ((BX_CPU_THIS_PTR oszapc.op1_8 < 0x80 &&
BX_CPU_THIS_PTR oszapc.op2_8 == 0) ||
((BX_CPU_THIS_PTR oszapc.op1_8 & 0x80) &&
BX_CPU_THIS_PTR oszapc.op2_8 == 0xff));
break;
case BX_INSTR_IMUL16:
case BX_INSTR_IMUL_AX:
cf = ! ((BX_CPU_THIS_PTR oszapc.op1_16 < 0x8000 &&
BX_CPU_THIS_PTR oszapc.op2_16 == 0) ||
((BX_CPU_THIS_PTR oszapc.op1_16 & 0x8000) &&
BX_CPU_THIS_PTR oszapc.op2_16 == 0xffff));
break;
case BX_INSTR_IMUL32:
case BX_INSTR_IMUL_EAX:
cf = ! ((BX_CPU_THIS_PTR oszapc.op1_32 < 0x80000000 &&
BX_CPU_THIS_PTR oszapc.op2_32 == 0) ||
((BX_CPU_THIS_PTR oszapc.op1_32 & 0x80000000) &&
BX_CPU_THIS_PTR oszapc.op2_32 == 0xffffffff));
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_IMUL64:
case BX_INSTR_IMUL_RAX:
cf = ! ((BX_CPU_THIS_PTR oszapc.op1_64 < BX_CONST64(0x8000000000000000) &&
BX_CPU_THIS_PTR oszapc.op2_64 == 0) ||
((BX_CPU_THIS_PTR oszapc.op1_64 & BX_CONST64(0x8000000000000000)) &&
BX_CPU_THIS_PTR oszapc.op2_64 == BX_CONST64(0xffffffffffffffff)));
break;
#endif
case BX_INSTR_MUL_AL:
cf = (BX_CPU_THIS_PTR oszapc.op2_8 != 0);
break;
case BX_INSTR_MUL16:
case BX_INSTR_MUL_AX:
cf = (BX_CPU_THIS_PTR oszapc.op2_16 != 0);
break;
case BX_INSTR_MUL32:
case BX_INSTR_MUL_EAX:
cf = (BX_CPU_THIS_PTR oszapc.op2_32 != 0);
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
case BX_INSTR_MUL_RAX:
cf = (BX_CPU_THIS_PTR oszapc.op2_64 != 0);
break;
#endif
@ -332,7 +360,9 @@ bx_bool BX_CPU_C::get_AFLazy(void)
case BX_INSTR_SAR64:
case BX_INSTR_SHR64:
case BX_INSTR_SHL64:
case BX_INSTR_MUL64:
case BX_INSTR_IMUL_RAX:
case BX_INSTR_IMUL64:
case BX_INSTR_MUL_RAX:
#endif
case BX_INSTR_SAR8:
case BX_INSTR_SAR16:
@ -343,9 +373,14 @@ bx_bool BX_CPU_C::get_AFLazy(void)
case BX_INSTR_SHL8:
case BX_INSTR_SHL16:
case BX_INSTR_SHL32:
case BX_INSTR_MUL8:
case BX_INSTR_MUL16:
case BX_INSTR_MUL32:
case BX_INSTR_IMUL16:
case BX_INSTR_IMUL32:
case BX_INSTR_IMUL_AL:
case BX_INSTR_IMUL_AX:
case BX_INSTR_IMUL_EAX:
case BX_INSTR_MUL_AL:
case BX_INSTR_MUL_AX:
case BX_INSTR_MUL_EAX:
af = 0;
break;
default:
@ -461,23 +496,38 @@ bx_bool BX_CPU_C::get_ZFLazy(void)
zf = (BX_CPU_THIS_PTR oszapc.result_64 == 0);
break;
#endif
case BX_INSTR_MUL8:
case BX_INSTR_IMUL_AL:
case BX_INSTR_MUL_AL:
zf = (BX_CPU_THIS_PTR oszapc.op1_8 |
BX_CPU_THIS_PTR oszapc.op2_8) == 0;
break;
case BX_INSTR_MUL16:
case BX_INSTR_IMUL_AX:
case BX_INSTR_MUL_AX:
zf = (BX_CPU_THIS_PTR oszapc.op1_16 |
BX_CPU_THIS_PTR oszapc.op2_16) == 0;
break;
case BX_INSTR_MUL32:
case BX_INSTR_IMUL_EAX:
case BX_INSTR_MUL_EAX:
zf = (BX_CPU_THIS_PTR oszapc.op1_32 |
BX_CPU_THIS_PTR oszapc.op2_32) == 0;
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
case BX_INSTR_IMUL_RAX:
case BX_INSTR_MUL_RAX:
zf = (BX_CPU_THIS_PTR oszapc.op1_64 |
BX_CPU_THIS_PTR oszapc.op2_64) == 0;
break;
#endif
case BX_INSTR_IMUL16:
zf = (BX_CPU_THIS_PTR oszapc.op1_16 == 0);
break;
case BX_INSTR_IMUL32:
zf = (BX_CPU_THIS_PTR oszapc.op1_32 == 0);
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_IMUL64:
zf = (BX_CPU_THIS_PTR oszapc.op1_64 == 0);
break;
#endif
case BX_INSTR_BITSCAN16:
case BX_INSTR_BITSCAN32:
@ -590,19 +640,34 @@ bx_bool BX_CPU_C::get_SFLazy(void)
sf = (BX_CPU_THIS_PTR oszapc.result_64 >= BX_CONST64(0x8000000000000000));
break;
#endif
case BX_INSTR_MUL8:
case BX_INSTR_IMUL_AL:
case BX_INSTR_MUL_AL:
sf = (BX_CPU_THIS_PTR oszapc.op2_8 >= 0x80);
break;
case BX_INSTR_MUL16:
case BX_INSTR_IMUL_AX:
case BX_INSTR_MUL_AX:
sf = (BX_CPU_THIS_PTR oszapc.op2_16 >= 0x8000);
break;
case BX_INSTR_MUL32:
case BX_INSTR_IMUL_EAX:
case BX_INSTR_MUL_EAX:
sf = (BX_CPU_THIS_PTR oszapc.op2_32 >= 0x80000000);
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
case BX_INSTR_IMUL_RAX:
case BX_INSTR_MUL_RAX:
sf = (BX_CPU_THIS_PTR oszapc.op2_64 >= BX_CONST64(0x8000000000000000));
break;
#endif
case BX_INSTR_IMUL16:
sf = (BX_CPU_THIS_PTR oszapc.op1_16 >= 0x8000);
break;
case BX_INSTR_IMUL32:
sf = (BX_CPU_THIS_PTR oszapc.op1_32 >= 0x80000000);
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_IMUL64:
sf = (BX_CPU_THIS_PTR oszapc.op1_64 >= BX_CONST64(0x8000000000000000));
break;
#endif
default:
sf = 0; // Keep compiler quiet.
@ -818,17 +883,46 @@ bx_bool BX_CPU_C::get_OFLazy(void)
BX_CPU_THIS_PTR oszapc.result_64) & BX_CONST64(0x8000000000000000)) > 0;
break;
#endif
case BX_INSTR_MUL8:
case BX_INSTR_IMUL_AL:
of = ! ((BX_CPU_THIS_PTR oszapc.op1_8 < 0x80 &&
BX_CPU_THIS_PTR oszapc.op2_8 == 0) ||
((BX_CPU_THIS_PTR oszapc.op1_8 & 0x80) &&
BX_CPU_THIS_PTR oszapc.op2_8 == 0xff));
break;
case BX_INSTR_IMUL16:
case BX_INSTR_IMUL_AX:
of = ! ((BX_CPU_THIS_PTR oszapc.op1_16 < 0x8000 &&
BX_CPU_THIS_PTR oszapc.op2_16 == 0) ||
((BX_CPU_THIS_PTR oszapc.op1_16 & 0x8000) &&
BX_CPU_THIS_PTR oszapc.op2_16 == 0xffff));
break;
case BX_INSTR_IMUL32:
case BX_INSTR_IMUL_EAX:
of = ! ((BX_CPU_THIS_PTR oszapc.op1_32 < 0x80000000 &&
BX_CPU_THIS_PTR oszapc.op2_32 == 0) ||
((BX_CPU_THIS_PTR oszapc.op1_32 & 0x80000000) &&
BX_CPU_THIS_PTR oszapc.op2_32 == 0xffffffff));
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_IMUL64:
case BX_INSTR_IMUL_RAX:
of = ! ((BX_CPU_THIS_PTR oszapc.op1_64 < BX_CONST64(0x8000000000000000) &&
BX_CPU_THIS_PTR oszapc.op2_64 == 0) ||
((BX_CPU_THIS_PTR oszapc.op1_64 & BX_CONST64(0x8000000000000000)) &&
BX_CPU_THIS_PTR oszapc.op2_64 == BX_CONST64(0xffffffffffffffff)));
break;
#endif
case BX_INSTR_MUL_AL:
of = (BX_CPU_THIS_PTR oszapc.op2_8 != 0);
break;
case BX_INSTR_MUL16:
case BX_INSTR_MUL_AX:
of = (BX_CPU_THIS_PTR oszapc.op2_16 != 0);
break;
case BX_INSTR_MUL32:
case BX_INSTR_MUL_EAX:
of = (BX_CPU_THIS_PTR oszapc.op2_32 != 0);
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
case BX_INSTR_MUL_RAX:
of = (BX_CPU_THIS_PTR oszapc.op2_64 != 0);
break;
#endif
@ -946,17 +1040,24 @@ bx_bool BX_CPU_C::get_PFLazy(void)
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_64];
break;
#endif
case BX_INSTR_MUL8:
case BX_INSTR_IMUL_AL:
case BX_INSTR_MUL_AL:
pf = bx_parity_lookup[BX_CPU_THIS_PTR oszapc.op1_8];
break;
case BX_INSTR_MUL16:
case BX_INSTR_IMUL_AX:
case BX_INSTR_IMUL16:
case BX_INSTR_MUL_AX:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.op1_16];
break;
case BX_INSTR_MUL32:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.op1_16];
case BX_INSTR_IMUL_EAX:
case BX_INSTR_IMUL32:
case BX_INSTR_MUL_EAX:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.op1_32];
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
case BX_INSTR_IMUL_RAX:
case BX_INSTR_IMUL64:
case BX_INSTR_MUL_RAX:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.op1_64];
break;
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: lazy_flags.h,v 1.16 2004-08-26 20:37:50 sshwarts Exp $
// $Id: lazy_flags.h,v 1.17 2004-08-30 21:47:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -94,10 +94,21 @@
#define BX_INSTR_SAR32 51
#define BX_INSTR_SAR64 52
#define BX_INSTR_MUL8 53
#define BX_INSTR_MUL16 54
#define BX_INSTR_MUL32 55
#define BX_INSTR_MUL64 56
#define BX_INSTR_MUL_AL 53
#define BX_INSTR_MUL_AX 54
#define BX_INSTR_MUL_EAX 55
#define BX_INSTR_MUL_RAX 56
#define BX_INSTR_IMUL_AL 57
#define BX_INSTR_IMUL_AX 58
#define BX_INSTR_IMUL_EAX 59
#define BX_INSTR_IMUL_RAX 60
// BX_INSTR_IMUL8 not exists, leave number for alignment
#define BX_INSTR_IMUL16 62
#define BX_INSTR_IMUL32 63
#define BX_INSTR_IMUL64 64
#define BX_LF_INDEX_OSZAPC 1
#define BX_LF_INDEX_OSZAP 2

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult16.cc,v 1.15 2004-08-26 20:37:50 sshwarts Exp $
// $Id: mult16.cc,v 1.16 2004-08-30 21:47:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -51,7 +51,7 @@ BX_CPU_C::MUL_AXEw(bxInstruction_c *i)
Bit16u product_16h = product_32 >> 16;
/* set EFLAGS */
SET_FLAGS_OSZAPC_S1S2_16(product_16l, product_16h, BX_INSTR_MUL16);
SET_FLAGS_OSZAPC_S1S2_16(product_16l, product_16h, BX_INSTR_MUL_AX);
/* now write product back to destination */
AX = product_16l;
@ -62,8 +62,6 @@ BX_CPU_C::MUL_AXEw(bxInstruction_c *i)
BX_CPU_C::IMUL_AXEw(bxInstruction_c *i)
{
Bit16s op1_16, op2_16;
Bit32s product_32;
Bit16u product_16h, product_16l;
op1_16 = AX;
@ -76,29 +74,19 @@ BX_CPU_C::IMUL_AXEw(bxInstruction_c *i)
read_virtual_word(i->seg(), RMAddr(i), (Bit16u *) &op2_16);
}
product_32 = ((Bit32s) op1_16) * ((Bit32s) op2_16);
product_16l = (product_32 & 0xFFFF);
product_16h = product_32 >> 16;
Bit32s product_32 = ((Bit32s) op1_16) * ((Bit32s) op2_16);
Bit16u product_16l = (product_32 & 0xFFFF);
Bit16u product_16h = product_32 >> 16;
/* now write product back to destination */
AX = product_16l;
DX = product_16h;
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r/m16: condition for clearing CF & OF:
* DX:AX = sign-extend of AX
*/
if ( (DX==0xffff) && (AX & 0x8000) ) {
SET_FLAGS_OxxxxC(0, 0);
}
else if ( (DX==0x0000) && (AX < 0x8000) ) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_16(product_16l, product_16h, BX_INSTR_IMUL_AX);
}
void
@ -189,9 +177,7 @@ BX_CPU_C::IDIV_AXEw(bxInstruction_c *i)
void
BX_CPU_C::IMUL_GwEwIw(bxInstruction_c *i)
{
Bit16u product_16l;
Bit16s op2_16, op3_16;
Bit32s product_32;
op3_16 = i->Iw();
@ -204,32 +190,24 @@ BX_CPU_C::IMUL_GwEwIw(bxInstruction_c *i)
read_virtual_word(i->seg(), RMAddr(i), (Bit16u *) &op2_16);
}
product_32 = op2_16 * op3_16;
product_16l = (product_32 & 0xFFFF);
Bit32s product_32 = op2_16 * op3_16;
Bit16u product_16l = (product_32 & 0xFFFF);
Bit16u product_16h = (product_32 >> 16);
/* now write product back to destination */
BX_WRITE_16BIT_REG(i->nnn(), product_16l);
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r16,r/m16,imm16: condition for clearing CF & OF:
* result exactly fits within r16
*/
if (product_32 > -32768 && product_32 < 32767) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_16(product_16l, product_16h, BX_INSTR_IMUL16);
}
void
BX_CPU_C::IMUL_GwEw(bxInstruction_c *i)
{
Bit16u product_16l;
Bit16s op1_16, op2_16;
Bit32s product_32;
/* op2 is a register or memory reference */
if (i->modC0()) {
@ -242,22 +220,16 @@ BX_CPU_C::IMUL_GwEw(bxInstruction_c *i)
op1_16 = BX_READ_16BIT_REG(i->nnn());
product_32 = op1_16 * op2_16;
product_16l = (product_32 & 0xFFFF);
Bit32s product_32 = op1_16 * op2_16;
Bit16u product_16l = (product_32 & 0xFFFF);
Bit16u product_16h = (product_32 >> 16);
/* now write product back to destination */
BX_WRITE_16BIT_REG(i->nnn(), product_16l);
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r16,r/m16,imm16: condition for clearing CF & OF:
* result exactly fits within r16
*/
if (product_32 > -32768 && product_32 < 32767) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_16(product_16l, product_16h, BX_INSTR_IMUL16);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult32.cc,v 1.15 2004-08-26 20:37:50 sshwarts Exp $
// $Id: mult32.cc,v 1.16 2004-08-30 21:47:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -59,7 +59,7 @@ BX_CPU_C::MUL_EAXEd(bxInstruction_c *i)
product_32h = (Bit32u) (product_64 >> 32);
/* set EFLAGS */
SET_FLAGS_OSZAPC_S1S2_32(product_32l, product_32h, BX_INSTR_MUL32);
SET_FLAGS_OSZAPC_S1S2_32(product_32l, product_32h, BX_INSTR_MUL_EAX);
/* now write product back to destination */
RAX = product_32l;
@ -70,8 +70,6 @@ BX_CPU_C::MUL_EAXEd(bxInstruction_c *i)
BX_CPU_C::IMUL_EAXEd(bxInstruction_c *i)
{
Bit32s op1_32, op2_32;
Bit64s product_64;
Bit32u product_32h, product_32l;
op1_32 = EAX;
@ -84,29 +82,19 @@ BX_CPU_C::IMUL_EAXEd(bxInstruction_c *i)
read_virtual_dword(i->seg(), RMAddr(i), (Bit32u *) &op2_32);
}
product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
product_32l = (Bit32u) (product_64 & 0xFFFFFFFF);
product_32h = (Bit32u) (product_64 >> 32);
Bit64s product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
Bit32u product_32l = (Bit32u) (product_64 & 0xFFFFFFFF);
Bit32u product_32h = (Bit32u) (product_64 >> 32);
/* now write product back to destination */
RAX = product_32l;
RDX = product_32h;
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r/m16: condition for clearing CF & OF:
* IMUL r/m32: condition for clearing CF & OF:
* EDX:EAX = sign-extend of EAX
*/
if ( (EDX==0xffffffff) && (EAX & 0x80000000) ) {
SET_FLAGS_OxxxxC(0, 0);
}
else if ( (EDX==0x00000000) && (EAX < 0x80000000) ) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_32(product_32l, product_32h, BX_INSTR_IMUL_EAX);
}
void
@ -193,8 +181,7 @@ BX_CPU_C::IDIV_EAXEd(bxInstruction_c *i)
void
BX_CPU_C::IMUL_GdEdId(bxInstruction_c *i)
{
Bit32s op2_32, op3_32, product_32;
Bit64s product_64;
Bit32s op2_32, op3_32;
op3_32 = i->Id();
@ -207,32 +194,24 @@ BX_CPU_C::IMUL_GdEdId(bxInstruction_c *i)
read_virtual_dword(i->seg(), RMAddr(i), (Bit32u *) &op2_32);
}
product_32 = op2_32 * op3_32;
product_64 = ((Bit64s) op2_32) * ((Bit64s) op3_32);
Bit64s product_64 = ((Bit64s) op2_32) * ((Bit64s) op3_32);
Bit32u product_32l = (product_64 & 0xFFFFFFFF);
Bit32u product_32h = (product_64 >> 32);
/* now write product back to destination */
BX_WRITE_32BIT_REGZ(i->nnn(), product_32);
BX_WRITE_32BIT_REGZ(i->nnn(), product_32l);
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r16,r/m16,imm16: condition for clearing CF & OF:
* result exactly fits within r16
* IMUL r32,r/m32,imm32: condition for clearing CF & OF:
* result exactly fits within r32
*/
if (product_64 == product_32) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_32(product_32l, product_32h, BX_INSTR_IMUL32);
}
void
BX_CPU_C::IMUL_GdEd(bxInstruction_c *i)
{
Bit32s op1_32, op2_32, product_32;
Bit64s product_64;
Bit32s op1_32, op2_32;
/* op2 is a register or memory reference */
if (i->modC0()) {
@ -245,22 +224,16 @@ BX_CPU_C::IMUL_GdEd(bxInstruction_c *i)
op1_32 = BX_READ_32BIT_REG(i->nnn());
product_32 = op1_32 * op2_32;
product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
Bit64s product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
Bit32u product_32l = (product_64 & 0xFFFFFFFF);
Bit32u product_32h = (product_64 >> 32);
/* now write product back to destination */
BX_WRITE_32BIT_REGZ(i->nnn(), product_32);
BX_WRITE_32BIT_REGZ(i->nnn(), product_32l);
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r16,r/m16,imm16: condition for clearing CF & OF:
* result exactly fits within r16
* IMUL r32,r/m32,imm32: condition for clearing CF & OF:
* result exactly fits within r32
*/
if (product_64 == product_32) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_32(product_32l, product_32h, BX_INSTR_IMUL32);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult64.cc,v 1.12 2004-08-26 20:37:50 sshwarts Exp $
// $Id: mult64.cc,v 1.13 2004-08-30 21:47:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -229,7 +229,7 @@ BX_CPU_C::MUL_RAXEq(bxInstruction_c *i)
long_mul(&product_128,op1_64,op2_64);
/* set EFLAGS */
SET_FLAGS_OSZAPC_S1S2_64(product_128.lo, product_128.hi, BX_INSTR_MUL64);
SET_FLAGS_OSZAPC_S1S2_64(product_128.lo, product_128.hi, BX_INSTR_MUL_RAX);
/* now write product back to destination */
RAX = product_128.lo;
@ -264,20 +264,10 @@ BX_CPU_C::IMUL_RAXEq(bxInstruction_c *i)
RDX = product_128.hi;
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r/m16: condition for clearing CF & OF:
* IMUL r/m64: condition for clearing CF & OF:
* RDX:RAX = sign-extend of RAX
*/
if ( (RDX==BX_CONST64(0xffffffffffffffff)) && (RAX & BX_CONST64(0x8000000000000000)) ) {
SET_FLAGS_OxxxxC(0, 0);
}
else if ( (RDX==BX_CONST64(0x0000000000000000)) && (RAX < BX_CONST64(0x8000000000000000)) ) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_64(product_128.lo, product_128.hi, BX_INSTR_IMUL_RAX);
}
void
@ -370,7 +360,7 @@ BX_CPU_C::IDIV_RAXEq(bxInstruction_c *i)
void
BX_CPU_C::IMUL_GqEqId(bxInstruction_c *i)
{
Bit64s op2_64, op3_64, product_64;
Bit64s op2_64, op3_64;
Bit128s product_128;
op3_64 = (Bit32s) i->Id();
@ -384,30 +374,22 @@ BX_CPU_C::IMUL_GqEqId(bxInstruction_c *i)
read_virtual_qword(i->seg(), RMAddr(i), (Bit64u *) &op2_64);
}
product_64 = op2_64 * op3_64;
long_imul(&product_128,op2_64,op3_64);
/* now write product back to destination */
BX_WRITE_64BIT_REG(i->nnn(), product_64);
BX_WRITE_64BIT_REG(i->nnn(), product_128.lo);
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r16,r/m16,imm16: condition for clearing CF & OF:
* result exactly fits within r16
* IMUL r64,r/m64,imm64: condition for clearing CF & OF:
* result exactly fits within r64
*/
if (product_128.lo == product_64) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_64(product_128.lo, product_128.hi, BX_INSTR_IMUL64);
}
void
BX_CPU_C::IMUL_GqEq(bxInstruction_c *i)
{
Bit64s op1_64, op2_64, product_64;
Bit64s op1_64, op2_64;
Bit128s product_128;
/* op2 is a register or memory reference */
@ -421,24 +403,16 @@ BX_CPU_C::IMUL_GqEq(bxInstruction_c *i)
op1_64 = BX_READ_64BIT_REG(i->nnn());
product_64 = op1_64 * op2_64;
long_imul(&product_128,op1_64,op2_64);
/* now write product back to destination */
BX_WRITE_64BIT_REG(i->nnn(), product_64);
BX_WRITE_64BIT_REG(i->nnn(), product_128.lo);
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r16,r/m16,imm16: condition for clearing CF & OF:
* result exactly fits within r16
* IMUL r64,r/m64,imm64: condition for clearing CF & OF:
* result exactly fits within r64
*/
if (product_128.lo == product_64) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_64(product_128.lo, product_128.hi, BX_INSTR_IMUL64);
}
#endif /* if BX_SUPPORT_X86_64 */

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult8.cc,v 1.15 2004-08-26 20:37:50 sshwarts Exp $
// $Id: mult8.cc,v 1.16 2004-08-30 21:47:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -52,7 +52,7 @@ BX_CPU_C::MUL_ALEb(bxInstruction_c *i)
Bit8u product_8h = product_16 >> 8;
/* set EFLAGS */
SET_FLAGS_OSZAPC_S1S2_8(product_8l, product_8h, BX_INSTR_MUL8);
SET_FLAGS_OSZAPC_S1S2_8(product_8l, product_8h, BX_INSTR_MUL_AL);
/* now write product back to destination */
AX = product_16;
@ -76,21 +76,17 @@ BX_CPU_C::IMUL_ALEb(bxInstruction_c *i)
Bit16s product_16 = op1 * op2;
/* now write product back to destination */
AX = product_16;
Bit8u product_8l = (product_16 & 0xFF);
Bit8u product_8h = product_16 >> 8;
/* set EFLAGS:
* IMUL affects the following flags: C,O
* IMUL r/m8: condition for clearing CF & OF:
* AL = sign-extend of AL to 16 bits
*/
Bit16u upper_bits = AX & 0xff80;
if (upper_bits==0xff80 || upper_bits==0x0000) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
SET_FLAGS_OSZAPC_S1S2_8(product_8l, product_8h, BX_INSTR_IMUL_AL);
/* now write product back to destination */
AX = product_16;
}
void

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: misc_mem.cc,v 1.47 2004-08-26 07:58:33 vruppert Exp $
// $Id: misc_mem.cc,v 1.48 2004-08-30 21:47:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -109,7 +109,7 @@ BX_MEM_C::~BX_MEM_C(void)
void
BX_MEM_C::init_memory(int memsize)
{
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.47 2004-08-26 07:58:33 vruppert Exp $"));
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.48 2004-08-30 21:47:24 sshwarts Exp $"));
// you can pass 0 if memory has been allocated already through
// the constructor, or the desired size of memory if it hasn't
// BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
@ -187,6 +187,7 @@ BX_MEM_C::load_ROM(const char *path, Bit32u romaddress, Bit8u type)
}
size = stat_buf.st_size;
BX_INFO(("ROM image size is %ld ...", size));
if (type > 0) {
max_size = 0x10000;
@ -199,14 +200,14 @@ BX_MEM_C::load_ROM(const char *path, Bit32u romaddress, Bit8u type)
}
if (type == 0) {
if ( (romaddress + size) != 0x100000 ) {
BX_PANIC(("ROM: Sytem BIOS must end at 0xfffff"));
BX_PANIC(("ROM: System BIOS must end at 0xfffff"));
return;
}
} else {
if ((size % 512) != 0) {
BX_PANIC(("ROM: ROM image size must multiple of 512"));
return;
}
// if ((size % 512) != 0) {
// BX_PANIC(("ROM: ROM image size must be multiple of 512"));
// return;
// }
if ((romaddress % 2048) != 0) {
BX_PANIC(("ROM: ROM image must start at a 2k boundary"));
return;
@ -216,7 +217,6 @@ BX_MEM_C::load_ROM(const char *path, Bit32u romaddress, Bit8u type)
return;
}
}
offset = 0;
while (size > 0) {
ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[romaddress + offset], size);
@ -230,8 +230,7 @@ BX_MEM_C::load_ROM(const char *path, Bit32u romaddress, Bit8u type)
BX_INFO(("rom at 0x%05x/%u ('%s')",
(unsigned) romaddress,
(unsigned) stat_buf.st_size,
path
));
path));
}
#endif // #if BX_PROVIDE_CPU_MEMORY