Commented problematic check in misc_mem.cc
Implemnted lazy-flags and undocumented flags handling for IMUL instructions
This commit is contained in:
parent
14d5b69d96
commit
016207b222
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user