From 016207b222361ef801ca06e71be290c122f57057 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Mon, 30 Aug 2004 21:47:24 +0000 Subject: [PATCH] Commented problematic check in misc_mem.cc Implemnted lazy-flags and undocumented flags handling for IMUL instructions --- bochs/cpu/cpu.h | 3 +- bochs/cpu/cpuid.cc | 6 +- bochs/cpu/lazy_flags.cc | 155 ++++++++++++++++++++++++++++++++------- bochs/cpu/lazy_flags.h | 21 ++++-- bochs/cpu/mult16.cc | 56 ++++---------- bochs/cpu/mult32.cc | 73 ++++++------------ bochs/cpu/mult64.cc | 54 ++++---------- bochs/cpu/mult8.cc | 20 ++--- bochs/memory/misc_mem.cc | 19 +++-- 9 files changed, 216 insertions(+), 191 deletions(-) diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index ed8294c0c..6c76de76a 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -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 diff --git a/bochs/cpu/cpuid.cc b/bochs/cpu/cpuid.cc index c1803430c..6e5c3d576 100755 --- a/bochs/cpu/cpuid.cc +++ b/bochs/cpu/cpuid.cc @@ -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; diff --git a/bochs/cpu/lazy_flags.cc b/bochs/cpu/lazy_flags.cc index 2aa08e9f6..32e15b49d 100644 --- a/bochs/cpu/lazy_flags.cc +++ b/bochs/cpu/lazy_flags.cc @@ -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 diff --git a/bochs/cpu/lazy_flags.h b/bochs/cpu/lazy_flags.h index 00ae178ed..dc8ac1d26 100644 --- a/bochs/cpu/lazy_flags.h +++ b/bochs/cpu/lazy_flags.h @@ -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 diff --git a/bochs/cpu/mult16.cc b/bochs/cpu/mult16.cc index 8b61da59e..a07aff3c4 100644 --- a/bochs/cpu/mult16.cc +++ b/bochs/cpu/mult16.cc @@ -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); } diff --git a/bochs/cpu/mult32.cc b/bochs/cpu/mult32.cc index 95ffddd94..fb6e38da6 100644 --- a/bochs/cpu/mult32.cc +++ b/bochs/cpu/mult32.cc @@ -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); } diff --git a/bochs/cpu/mult64.cc b/bochs/cpu/mult64.cc index d3a8e071c..c7768f80f 100644 --- a/bochs/cpu/mult64.cc +++ b/bochs/cpu/mult64.cc @@ -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 */ diff --git a/bochs/cpu/mult8.cc b/bochs/cpu/mult8.cc index a917f1b03..b011dffdc 100644 --- a/bochs/cpu/mult8.cc +++ b/bochs/cpu/mult8.cc @@ -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 diff --git a/bochs/memory/misc_mem.cc b/bochs/memory/misc_mem.cc index e4c748a13..3ebfe9663 100644 --- a/bochs/memory/misc_mem.cc +++ b/bochs/memory/misc_mem.cc @@ -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