LAZY-FLAGS for MUL instructions

undocumented flags handling for MUL instructions
This commit is contained in:
Stanislav Shwartsman 2004-08-26 20:37:50 +00:00
parent 986f879a85
commit f2294e7c29
7 changed files with 109 additions and 40 deletions

View File

@ -20,8 +20,8 @@ Changes to next release:
- fixed using invalid segment register for MOV instruction (h.johansson)
- fixed ET bit mismatch between CR0 and SMSW instruction
- fixed possible simulator #DIVZERO fault when executing IDIV instruction
- fixed undocumented flags handling for BTS, BTR and SHR instructions
(Stanislav Shwartsman)
- fixed undocumented flags handling for BTS, BTR, SHR and MUL
instructions (Stanislav Shwartsman)
- fixed CF flag handling for SHL instruction in x86-64 mode
(Stanislav Shwartsman)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: lazy_flags.cc,v 1.22 2004-08-18 20:49:31 sshwarts Exp $
// $Id: lazy_flags.cc,v 1.23 2004-08-26 20:37:50 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -227,6 +227,20 @@ bx_bool BX_CPU_C::get_CFLazy(void)
(BX_CPU_THIS_PTR oszapc.op1_64 >>
(64 - BX_CPU_THIS_PTR oszapc.op2_64)) & 0x01;
break;
#endif
case BX_INSTR_MUL8:
cf = (BX_CPU_THIS_PTR oszapc.op2_8 != 0);
break;
case BX_INSTR_MUL16:
cf = (BX_CPU_THIS_PTR oszapc.op2_16 != 0);
break;
case BX_INSTR_MUL32:
cf = (BX_CPU_THIS_PTR oszapc.op2_32 != 0);
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
cf = (BX_CPU_THIS_PTR oszapc.op2_64 != 0);
break;
#endif
default:
cf = 0; // Keep compiler quiet.
@ -318,6 +332,7 @@ bx_bool BX_CPU_C::get_AFLazy(void)
case BX_INSTR_SAR64:
case BX_INSTR_SHR64:
case BX_INSTR_SHL64:
case BX_INSTR_MUL64:
#endif
case BX_INSTR_SAR8:
case BX_INSTR_SAR16:
@ -328,6 +343,9 @@ 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:
af = 0;
break;
default:
@ -442,6 +460,24 @@ bx_bool BX_CPU_C::get_ZFLazy(void)
case BX_INSTR_SHL64:
zf = (BX_CPU_THIS_PTR oszapc.result_64 == 0);
break;
#endif
case BX_INSTR_MUL8:
zf = (BX_CPU_THIS_PTR oszapc.op1_8 |
BX_CPU_THIS_PTR oszapc.op2_8) == 0;
break;
case BX_INSTR_MUL16:
zf = (BX_CPU_THIS_PTR oszapc.op1_16 |
BX_CPU_THIS_PTR oszapc.op2_16) == 0;
break;
case BX_INSTR_MUL32:
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:
zf = (BX_CPU_THIS_PTR oszapc.op1_64 |
BX_CPU_THIS_PTR oszapc.op2_64) == 0;
break;
#endif
case BX_INSTR_BITSCAN16:
case BX_INSTR_BITSCAN32:
@ -553,6 +589,20 @@ bx_bool BX_CPU_C::get_SFLazy(void)
case BX_INSTR_BITSCAN64:
sf = (BX_CPU_THIS_PTR oszapc.result_64 >= BX_CONST64(0x8000000000000000));
break;
#endif
case BX_INSTR_MUL8:
sf = (BX_CPU_THIS_PTR oszapc.op2_8 >= 0x80);
break;
case BX_INSTR_MUL16:
sf = (BX_CPU_THIS_PTR oszapc.op2_16 >= 0x8000);
break;
case BX_INSTR_MUL32:
sf = (BX_CPU_THIS_PTR oszapc.op2_32 >= 0x80000000);
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
sf = (BX_CPU_THIS_PTR oszapc.op2_64 >= BX_CONST64(0x8000000000000000));
break;
#endif
default:
sf = 0; // Keep compiler quiet.
@ -759,6 +809,20 @@ bx_bool BX_CPU_C::get_OFLazy(void)
else
of = (BX_CPU_THIS_PTR eflags.val32 >> 11) & 1; // Old val
break;
#endif
case BX_INSTR_MUL8:
of = (BX_CPU_THIS_PTR oszapc.op2_8 != 0);
break;
case BX_INSTR_MUL16:
of = (BX_CPU_THIS_PTR oszapc.op2_16 != 0);
break;
case BX_INSTR_MUL32:
of = (BX_CPU_THIS_PTR oszapc.op2_32 != 0);
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
of = (BX_CPU_THIS_PTR oszapc.op2_64 != 0);
break;
#endif
default:
of = 0; // Keep compiler happy.
@ -873,6 +937,20 @@ bx_bool BX_CPU_C::get_PFLazy(void)
case BX_INSTR_BITSCAN64:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_64];
break;
#endif
case BX_INSTR_MUL8:
pf = bx_parity_lookup[BX_CPU_THIS_PTR oszapc.op1_8];
break;
case BX_INSTR_MUL16:
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];
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_MUL64:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.op1_64];
break;
#endif
default:
pf = 0; // Keep compiler quiet.

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: lazy_flags.h,v 1.15 2004-08-18 20:49:31 sshwarts Exp $
// $Id: lazy_flags.h,v 1.16 2004-08-26 20:37:50 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -94,6 +94,11 @@
#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_LF_INDEX_OSZAPC 1
#define BX_LF_INDEX_OSZAP 2

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult16.cc,v 1.14 2004-08-18 19:27:52 sshwarts Exp $
// $Id: mult16.cc,v 1.15 2004-08-26 20:37:50 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -33,8 +33,7 @@
void
BX_CPU_C::MUL_AXEw(bxInstruction_c *i)
{
Bit16u op1_16, op2_16, product_16h, product_16l;
Bit32u product_32;
Bit16u op1_16, op2_16;
op1_16 = AX;
@ -47,20 +46,16 @@ BX_CPU_C::MUL_AXEw(bxInstruction_c *i)
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
}
product_32 = ((Bit32u) op1_16) * ((Bit32u) op2_16);
product_16l = (product_32 & 0xFFFF);
product_16h = product_32 >> 16;
Bit32u product_32 = ((Bit32u) op1_16) * ((Bit32u) op2_16);
Bit16u product_16l = (product_32 & 0xFFFF);
Bit16u product_16h = product_32 >> 16;
/* set EFLAGS */
SET_FLAGS_OSZAPC_S1S2_16(product_16l, product_16h, BX_INSTR_MUL16);
/* now write product back to destination */
AX = product_16l;
DX = product_16h;
/* set eflags:
* MUL affects the following flags: C,O
*/
bx_bool temp_flag = (product_16h != 0);
SET_FLAGS_OxxxxC(temp_flag, temp_flag);
}
void

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult32.cc,v 1.14 2004-08-18 19:27:52 sshwarts Exp $
// $Id: mult32.cc,v 1.15 2004-08-26 20:37:50 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -58,16 +58,12 @@ BX_CPU_C::MUL_EAXEd(bxInstruction_c *i)
product_32l = (Bit32u) (product_64 & 0xFFFFFFFF);
product_32h = (Bit32u) (product_64 >> 32);
/* set EFLAGS */
SET_FLAGS_OSZAPC_S1S2_32(product_32l, product_32h, BX_INSTR_MUL32);
/* now write product back to destination */
RAX = product_32l;
RDX = product_32h;
/* set eflags:
* MUL affects the following flags: C,O
*/
bx_bool temp_flag = (product_32h != 0);
SET_FLAGS_OxxxxC(temp_flag, temp_flag);
}
void

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult64.cc,v 1.11 2004-08-18 21:29:07 sshwarts Exp $
// $Id: mult64.cc,v 1.12 2004-08-26 20:37:50 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -228,16 +228,12 @@ 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);
/* now write product back to destination */
RAX = product_128.lo;
RDX = product_128.hi;
/* set eflags:
* MUL affects the following flags: C,O
*/
bx_bool temp_flag = (product_128.hi != 0);
SET_FLAGS_OxxxxC(temp_flag, temp_flag);
}
void

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult8.cc,v 1.14 2004-08-18 19:27:52 sshwarts Exp $
// $Id: mult8.cc,v 1.15 2004-08-26 20:37:50 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -46,14 +46,13 @@ BX_CPU_C::MUL_ALEb(bxInstruction_c *i)
read_virtual_byte(i->seg(), RMAddr(i), &op2);
}
Bit16u product_16 = op1 * op2;
Bit32u product_16 = ((Bit16u) op1) * ((Bit16u) op2);
/* set EFLAGS:
* MUL affects the following flags: C,O
*/
Bit8u product_8l = (product_16 & 0xFF);
Bit8u product_8h = product_16 >> 8;
bx_bool temp_flag = ((product_16 & 0xFF00) != 0);
SET_FLAGS_OxxxxC(temp_flag, temp_flag);
/* set EFLAGS */
SET_FLAGS_OSZAPC_S1S2_8(product_8l, product_8h, BX_INSTR_MUL8);
/* now write product back to destination */
AX = product_16;