Fixed undocumented flags handling for some instructions.

Bugfix for CF flag handling for SHL64 instruction
This commit is contained in:
Stanislav Shwartsman 2004-08-14 19:34:02 +00:00
parent a70ce6459f
commit 1732e54baa
7 changed files with 56 additions and 41 deletions

View File

@ -19,6 +19,10 @@ Changes to next release:
matches Intel docs
- fixed using invalid segment register for MOV instruction (h.johansson)
- fixed ET bit mismatch between CR0 and SMSW instruction
- fixed undocumented flags handling for BTS, BTR and SHR instructions
(Stanislav Shwartsman)
- fixed CF flag handling for SHL instruction in x86-64 mode
(Stanislav Shwartsman)
- FPU
- totally rewritten all FPU code based on softfloat library

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: bcd.cc,v 1.12 2004-03-26 12:43:19 sshwarts Exp $
// $Id: bcd.cc,v 1.13 2004-08-14 19:34:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -36,7 +36,7 @@
BX_CPU_C::AAA(bxInstruction_c *)
{
/*
* Note: This istruction incorrectly documented in Intel's materials.
* Note: This instruction incorrectly documented in Intel's materials.
* The right description is:
*
* IF (((AL and 0FH) > 9) or (AF==1)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: bit.cc,v 1.18 2004-08-13 20:00:03 sshwarts Exp $
// $Id: bit.cc,v 1.19 2004-08-14 19:34:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -461,7 +461,8 @@ BX_CPU_C::BSF_GvEv(bxInstruction_c *i)
op1_64++;
op2_64 >>= 1;
}
set_ZF(0);
SET_FLAGS_OSZAPC_RESULT_64(op1_64, BX_INSTR_BITSCAN64);
/* now write result back to destination */
BX_WRITE_64BIT_REG(i->nnn(), op1_64);
@ -491,7 +492,8 @@ BX_CPU_C::BSF_GvEv(bxInstruction_c *i)
op1_32++;
op2_32 >>= 1;
}
set_ZF(0);
SET_FLAGS_OSZAPC_RESULT_32(op1_32, BX_INSTR_BITSCAN32);
/* now write result back to destination */
BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
@ -518,7 +520,8 @@ BX_CPU_C::BSF_GvEv(bxInstruction_c *i)
op1_16++;
op2_16 >>= 1;
}
set_ZF(0);
SET_FLAGS_OSZAPC_RESULT_16(op1_16, BX_INSTR_BITSCAN16);
/* now write result back to destination */
BX_WRITE_16BIT_REG(i->nnn(), op1_16);
@ -558,7 +561,8 @@ BX_CPU_C::BSR_GvEv(bxInstruction_c *i)
op1_64--;
op2_64 <<= 1;
}
set_ZF(0);
SET_FLAGS_OSZAPC_RESULT_64(op1_64, BX_INSTR_BITSCAN64);
/* now write result back to destination */
BX_WRITE_64BIT_REG(i->nnn(), op1_64);
@ -588,7 +592,8 @@ BX_CPU_C::BSR_GvEv(bxInstruction_c *i)
op1_32--;
op2_32 <<= 1;
}
set_ZF(0);
SET_FLAGS_OSZAPC_RESULT_32(op1_32, BX_INSTR_BITSCAN32);
/* now write result back to destination */
BX_WRITE_32BIT_REGZ(i->nnn(), op1_32);
@ -615,7 +620,8 @@ BX_CPU_C::BSR_GvEv(bxInstruction_c *i)
op1_16--;
op2_16 <<= 1;
}
set_ZF(0);
SET_FLAGS_OSZAPC_RESULT_16(op1_16, BX_INSTR_BITSCAN16);
/* now write result back to destination */
BX_WRITE_16BIT_REG(i->nnn(), op1_16);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.170 2004-08-13 20:00:03 sshwarts Exp $
// $Id: cpu.h,v 1.171 2004-08-14 19:34:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1457,15 +1457,13 @@ union {
#define ArithmeticalFlag(flag, lfMaskShift, eflagsBitShift) \
BX_SMF bx_bool get_##flag##Lazy(void); \
BX_SMF bx_bool getB_##flag(void) { \
if ( (BX_CPU_THIS_PTR lf_flags_status & (0xf<<lfMaskShift)) == \
((Bit32u) (BX_LF_INDEX_KNOWN<<lfMaskShift)) ) \
if ( (BX_CPU_THIS_PTR lf_flags_status & (0xf<<lfMaskShift)) == 0) \
return (BX_CPU_THIS_PTR eflags.val32 >> eflagsBitShift) & 1; \
else \
return get_##flag##Lazy(); \
} \
BX_SMF bx_bool get_##flag(void) { \
if ( (BX_CPU_THIS_PTR lf_flags_status & (0xf<<lfMaskShift)) == \
((Bit32u) (BX_LF_INDEX_KNOWN<<lfMaskShift)) ) \
if ( (BX_CPU_THIS_PTR lf_flags_status & (0xf<<lfMaskShift)) == 0) \
return BX_CPU_THIS_PTR eflags.val32 & (1<<eflagsBitShift); \
else \
return get_##flag##Lazy(); \
@ -1691,7 +1689,6 @@ union {
BX_SMF void CLD(bxInstruction_c *);
BX_SMF void STD(bxInstruction_c *);
BX_SMF void LAR_GvEw(bxInstruction_c *);
BX_SMF void LSL_GvEw(bxInstruction_c *);
BX_SMF void CLTS(bxInstruction_c *);
@ -1734,7 +1731,6 @@ union {
BX_SMF void SHLD_EdGd(bxInstruction_c *);
BX_SMF void SHLD_EwGw(bxInstruction_c *);
BX_SMF void BTS_EvGv(bxInstruction_c *);
BX_SMF void SHRD_EwGw(bxInstruction_c *);
@ -2645,7 +2641,6 @@ union {
#if BX_SUPPORT_X86_64
// 64 bit addressing
BX_SMF void Resolve64Mod0Rm0(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void Resolve64Mod0Rm1(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
BX_SMF void Resolve64Mod0Rm2(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
@ -2997,8 +2992,7 @@ BX_CPP_INLINE Bit32u bxICache_c::createFetchModeMask(BX_CPU_C *cpu) {
#if BX_SUPPORT_X86_64
| ((cpu->cpu_mode == BX_MODE_LONG_64)<<30)
#endif
| (1<<29) // iCache code.
;
| (1<<29); // iCache code.
}
#endif
@ -3094,7 +3088,6 @@ BX_CPU_C::set_SF(bx_bool val) {
BX_CPU_THIS_PTR eflags.val32 |= (!!val)<<7;
}
BX_CPP_INLINE void
BX_CPU_C::set_OF(bx_bool val) {
BX_CPU_THIS_PTR lf_flags_status &= 0x0fffff;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: lazy_flags.cc,v 1.13 2004-08-09 21:28:47 sshwarts Exp $
// $Id: lazy_flags.cc,v 1.14 2004-08-14 19:34:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -172,8 +172,11 @@ bx_bool BX_CPU_C::get_CFLazy(void)
case BX_INSTR_LOGIC8:
case BX_INSTR_LOGIC16:
case BX_INSTR_LOGIC32:
case BX_INSTR_BITSCAN16:
case BX_INSTR_BITSCAN32:
#if BX_SUPPORT_X86_64
case BX_INSTR_LOGIC64:
case BX_INSTR_BITSCAN64:
#endif
cf = 0;
break;
@ -228,7 +231,7 @@ bx_bool BX_CPU_C::get_CFLazy(void)
case BX_INSTR_SHL64:
cf =
(BX_CPU_THIS_PTR oszapc.op1_64 >>
(32 - BX_CPU_THIS_PTR oszapc.op2_64)) & 0x01;
(64 - BX_CPU_THIS_PTR oszapc.op2_64)) & 0x01;
break;
#endif
default:
@ -326,8 +329,11 @@ bx_bool BX_CPU_C::get_AFLazy(void)
case BX_INSTR_LOGIC8:
case BX_INSTR_LOGIC16:
case BX_INSTR_LOGIC32:
case BX_INSTR_BITSCAN16:
case BX_INSTR_BITSCAN32:
#if BX_SUPPORT_X86_64
case BX_INSTR_LOGIC64:
case BX_INSTR_BITSCAN64:
case BX_INSTR_SHR64:
case BX_INSTR_SHL64:
#endif
@ -338,7 +344,6 @@ bx_bool BX_CPU_C::get_AFLazy(void)
case BX_INSTR_SHL16:
case BX_INSTR_SHL32:
af = 0;
/* undefined */
break;
default:
af = 0; // Keep compiler quiet.
@ -462,6 +467,13 @@ bx_bool BX_CPU_C::get_ZFLazy(void)
zf = (BX_CPU_THIS_PTR oszapc.result_64 == 0);
break;
#endif
case BX_INSTR_BITSCAN16:
case BX_INSTR_BITSCAN32:
#if BX_SUPPORT_X86_64
case BX_INSTR_BITSCAN64:
#endif
zf = 0;
break;
default:
zf = 0;
BX_PANIC(("get_ZF: OSZAPC: unknown instr"));
@ -540,6 +552,7 @@ bx_bool BX_CPU_C::get_SFLazy(void)
case BX_INSTR_SCAS16:
case BX_INSTR_SHR16:
case BX_INSTR_SHL16:
case BX_INSTR_BITSCAN16:
sf = (BX_CPU_THIS_PTR oszapc.result_16 >= 0x8000);
break;
case BX_INSTR_LOGIC32:
@ -554,6 +567,7 @@ bx_bool BX_CPU_C::get_SFLazy(void)
case BX_INSTR_SCAS32:
case BX_INSTR_SHR32:
case BX_INSTR_SHL32:
case BX_INSTR_BITSCAN32:
sf = (BX_CPU_THIS_PTR oszapc.result_32 >= 0x80000000);
break;
#if BX_SUPPORT_X86_64
@ -569,6 +583,7 @@ bx_bool BX_CPU_C::get_SFLazy(void)
case BX_INSTR_SCAS64:
case BX_INSTR_SHR64:
case BX_INSTR_SHL64:
case BX_INSTR_BITSCAN64:
sf = (BX_CPU_THIS_PTR oszapc.result_64 >= BX_CONST64(0x8000000000000000));
break;
#endif
@ -635,7 +650,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
op1_b7 = BX_CPU_THIS_PTR oszapc.op1_8 & 0x80;
op2_b7 = BX_CPU_THIS_PTR oszapc.op2_8 & 0x80;
result_b7 = BX_CPU_THIS_PTR oszapc.result_8 & 0x80;
of = (op1_b7 == op2_b7) && (result_b7 ^ op2_b7);
break;
case BX_INSTR_ADD16:
@ -644,7 +658,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
op1_b15 = BX_CPU_THIS_PTR oszapc.op1_16 & 0x8000;
op2_b15 = BX_CPU_THIS_PTR oszapc.op2_16 & 0x8000;
result_b15 = BX_CPU_THIS_PTR oszapc.result_16 & 0x8000;
of = (op1_b15 == op2_b15) && (result_b15 ^ op2_b15);
break;
case BX_INSTR_ADD32:
@ -653,7 +666,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
op1_b31 = BX_CPU_THIS_PTR oszapc.op1_32 & 0x80000000;
op2_b31 = BX_CPU_THIS_PTR oszapc.op2_32 & 0x80000000;
result_b31 = BX_CPU_THIS_PTR oszapc.result_32 & 0x80000000;
of = (op1_b31 == op2_b31) && (result_b31 ^ op2_b31);
break;
#if BX_SUPPORT_X86_64
@ -663,7 +675,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
op1_b63 = BX_CPU_THIS_PTR oszapc.op1_64 & BX_CONST64(0x8000000000000000);
op2_b63 = BX_CPU_THIS_PTR oszapc.op2_64 & BX_CONST64(0x8000000000000000);
result_b63 = BX_CPU_THIS_PTR oszapc.result_64 & BX_CONST64(0x8000000000000000);
of = (op1_b63 == op2_b63) && (result_b63 ^ op2_b63);
break;
#endif
@ -675,7 +686,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
op1_b7 = BX_CPU_THIS_PTR oszapc.op1_8 & 0x80;
op2_b7 = BX_CPU_THIS_PTR oszapc.op2_8 & 0x80;
result_b7 = BX_CPU_THIS_PTR oszapc.result_8 & 0x80;
of = (op1_b7 ^ op2_b7) && (op1_b7 ^ result_b7);
break;
case BX_INSTR_SUB16:
@ -686,7 +696,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
op1_b15 = BX_CPU_THIS_PTR oszapc.op1_16 & 0x8000;
op2_b15 = BX_CPU_THIS_PTR oszapc.op2_16 & 0x8000;
result_b15 = BX_CPU_THIS_PTR oszapc.result_16 & 0x8000;
of = (op1_b15 ^ op2_b15) && (op1_b15 ^ result_b15);
break;
case BX_INSTR_SUB32:
@ -697,7 +706,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
op1_b31 = BX_CPU_THIS_PTR oszapc.op1_32 & 0x80000000;
op2_b31 = BX_CPU_THIS_PTR oszapc.op2_32 & 0x80000000;
result_b31 = BX_CPU_THIS_PTR oszapc.result_32 & 0x80000000;
of = (op1_b31 ^ op2_b31) && (op1_b31 ^ result_b31);
break;
#if BX_SUPPORT_X86_64
@ -709,7 +717,6 @@ bx_bool BX_CPU_C::get_OFLazy(void)
op1_b63 = BX_CPU_THIS_PTR oszapc.op1_64 & BX_CONST64(0x8000000000000000);
op2_b63 = BX_CPU_THIS_PTR oszapc.op2_64 & BX_CONST64(0x8000000000000000);
result_b63 = BX_CPU_THIS_PTR oszapc.result_64 & BX_CONST64(0x8000000000000000);
of = (op1_b63 ^ op2_b63) && (op1_b63 ^ result_b63);
break;
#endif
@ -730,8 +737,11 @@ bx_bool BX_CPU_C::get_OFLazy(void)
case BX_INSTR_LOGIC8:
case BX_INSTR_LOGIC16:
case BX_INSTR_LOGIC32:
case BX_INSTR_BITSCAN16:
case BX_INSTR_BITSCAN32:
#if BX_SUPPORT_X86_64
case BX_INSTR_LOGIC64:
case BX_INSTR_BITSCAN64:
#endif
of = 0;
break;
@ -739,26 +749,26 @@ bx_bool BX_CPU_C::get_OFLazy(void)
if (BX_CPU_THIS_PTR oszapc.op2_8 == 1)
of = (BX_CPU_THIS_PTR oszapc.op1_8 >= 0x80);
else
of = (BX_CPU_THIS_PTR eflags.val32 >> 11) & 1; // Old val
of = 0; /* undocumented, but hardware really does it */
break;
case BX_INSTR_SHR16:
if (BX_CPU_THIS_PTR oszapc.op2_16 == 1)
of = (BX_CPU_THIS_PTR oszapc.op1_16 >= 0x8000);
else
of = (BX_CPU_THIS_PTR eflags.val32 >> 11) & 1; // Old val
of = 0; /* undocumented, but hardware really does it */
break;
case BX_INSTR_SHR32:
if (BX_CPU_THIS_PTR oszapc.op2_32 == 1)
of = (BX_CPU_THIS_PTR oszapc.op1_32 >= 0x80000000);
else
of = (BX_CPU_THIS_PTR eflags.val32 >> 11) & 1; // Old val
of = 0; /* undocumented, but hardware really does it */
break;
#if BX_SUPPORT_X86_64
case BX_INSTR_SHR64:
if (BX_CPU_THIS_PTR oszapc.op2_64 == 1)
of = (BX_CPU_THIS_PTR oszapc.op1_64 >= BX_CONST64(0x8000000000000000));
else
of = (BX_CPU_THIS_PTR eflags.val32 >> 11) & 1; // Old val
of = 0; /* undocumented, but hardware really does it */
break;
#endif
case BX_INSTR_SHL8:
@ -878,6 +888,7 @@ bx_bool BX_CPU_C::get_PFLazy(void)
case BX_INSTR_SCAS16:
case BX_INSTR_SHR16:
case BX_INSTR_SHL16:
case BX_INSTR_BITSCAN16:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_16];
break;
case BX_INSTR_LOGIC32:
@ -892,6 +903,7 @@ bx_bool BX_CPU_C::get_PFLazy(void)
case BX_INSTR_SCAS32:
case BX_INSTR_SHR32:
case BX_INSTR_SHL32:
case BX_INSTR_BITSCAN32:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_32];
break;
#if BX_SUPPORT_X86_64
@ -907,6 +919,7 @@ bx_bool BX_CPU_C::get_PFLazy(void)
case BX_INSTR_SCAS64:
case BX_INSTR_SHR64:
case BX_INSTR_SHL64:
case BX_INSTR_BITSCAN64:
pf = bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_64];
break;
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: lazy_flags.h,v 1.9 2004-08-13 20:00:03 sshwarts Exp $
// $Id: lazy_flags.h,v 1.10 2004-08-14 19:34:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -97,12 +97,11 @@
#define BX_INSTR_LOGIC32 55
#define BX_INSTR_LOGIC64 56
#define BX_INSTR_BITSCAN8 57
// BX_INSTR_BITSCAN8 not exists, leave number for alignment
#define BX_INSTR_BITSCAN16 58
#define BX_INSTR_BITSCAN32 59
#define BX_INSTR_BITSCAN64 60
#define BX_LF_INDEX_KNOWN 0
#define BX_LF_INDEX_OSZAPC 1
#define BX_LF_INDEX_OSZAP 2

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult16.cc,v 1.12 2004-08-13 20:00:03 sshwarts Exp $
// $Id: mult16.cc,v 1.13 2004-08-14 19:34:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -227,7 +227,7 @@ BX_CPU_C::IMUL_GwEwIw(bxInstruction_c *i)
* result exactly fits within r16
*/
if (product_32 > -32768 && product_32 < 32767) {
if (product_32 > -32768 && product_32 < 32767) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
@ -265,7 +265,7 @@ BX_CPU_C::IMUL_GwEw(bxInstruction_c *i)
* result exactly fits within r16
*/
if (product_32 > -32768 && product_32 < 32767) {
if (product_32 > -32768 && product_32 < 32767) {
SET_FLAGS_OxxxxC(0, 0);
}
else {