- Fixed zero upper 32-bit part of GPR in x86-64 mode
- CMOV_GdEd should zero upper 32-bit part of GPR register even if the 'cmov' condition was false !
This commit is contained in:
parent
7d4a5ff1b2
commit
8221fa6838
@ -4,6 +4,9 @@ Changes after 2.3 release:
|
||||
- Fixed critical issue with 0x90 opcode (NOP) handling in x86-64 mode
|
||||
- Correctly detect inexact result by FPU
|
||||
- Do not save and restore XMM8-XMM15 registers when not in x86-64 mode
|
||||
- Fixed zero upper 32-bit part of GPR in x86-64 mode
|
||||
- CMOV_GdEd should zero upper 32-bit part of GPR register even if the
|
||||
'cmov' condition was false !
|
||||
- Several disasm and internal debugger fixes (again)
|
||||
|
||||
- General
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: arith16.cc,v 1.43 2006-03-26 18:58:00 sshwarts Exp $
|
||||
// $Id: arith16.cc,v 1.44 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -414,7 +414,6 @@ void BX_CPU_C::CBW(bxInstruction_c *i)
|
||||
void BX_CPU_C::CWD(bxInstruction_c *i)
|
||||
{
|
||||
/* CWD: no flags are affected */
|
||||
|
||||
if (AX & 0x8000) {
|
||||
DX = 0xFFFF;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: arith32.cc,v 1.49 2006-03-27 18:02:07 sshwarts Exp $
|
||||
// $Id: arith32.cc,v 1.50 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -409,14 +409,14 @@ void BX_CPU_C::CMP_EAXId(bxInstruction_c *i)
|
||||
|
||||
void BX_CPU_C::CWDE(bxInstruction_c *i)
|
||||
{
|
||||
/* CBW: no flags are effected */
|
||||
RAX = (Bit16s) AX;
|
||||
/* CWDE: no flags are effected */
|
||||
Bit32u tmp = (Bit16s) AX;
|
||||
RAX = tmp;
|
||||
}
|
||||
|
||||
void BX_CPU_C::CDQ(bxInstruction_c *i)
|
||||
{
|
||||
/* CDQ: no flags are affected */
|
||||
|
||||
if (EAX & 0x80000000) {
|
||||
RDX = 0xFFFFFFFF;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: bit.cc,v 1.30 2006-06-26 20:28:00 sshwarts Exp $
|
||||
// $Id: bit.cc,v 1.31 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -526,7 +526,7 @@ void BX_CPU_C::BSWAP_ERX(bxInstruction_c *i)
|
||||
val32 = (b0<<24) | (b1<<16) | (b2<<8) | b3; // zero extended
|
||||
|
||||
// in 64-bit mode, hi-order 32 bits are not modified
|
||||
BX_WRITE_32BIT_REG(i->opcodeReg(), val32);
|
||||
BX_WRITE_32BIT_REGZ(i->opcodeReg(), val32);
|
||||
#else
|
||||
BX_INFO(("BSWAP_ERX: required CPU >= 4, use --enable-cpu-level=4 option"));
|
||||
UndefinedOpcode(i);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.309 2007-01-25 19:09:36 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.310 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2489,6 +2489,11 @@ public: // for now...
|
||||
BX_SMF void PUSH64_GS(bxInstruction_c *);
|
||||
BX_SMF void POP64_GS(bxInstruction_c *);
|
||||
|
||||
BX_SMF void SGDT64_Ms(bxInstruction_c *);
|
||||
BX_SMF void SIDT64_Ms(bxInstruction_c *);
|
||||
BX_SMF void LGDT64_Ms(bxInstruction_c *);
|
||||
BX_SMF void LIDT64_Ms(bxInstruction_c *);
|
||||
|
||||
BX_SMF void SYSCALL(bxInstruction_c *i);
|
||||
BX_SMF void SYSRET(bxInstruction_c *i);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: data_xfer32.cc,v 1.40 2006-11-26 12:53:01 sshwarts Exp $
|
||||
// $Id: data_xfer32.cc,v 1.41 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -241,6 +241,7 @@ void BX_CPU_C::CMOV_GdEd(bxInstruction_c *i)
|
||||
if (condition) {
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op2_32);
|
||||
}
|
||||
BX_CLEAR_64BIT_HIGH(i->nnn()); // always clear upper part of the register
|
||||
#else
|
||||
BX_INFO(("CMOV_GdEd: -enable-cpu-level=6 required"));
|
||||
UndefinedOpcode(i);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode64.cc,v 1.103 2007-01-25 19:09:41 sshwarts Exp $
|
||||
// $Id: fetchdecode64.cc,v 1.104 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -426,10 +426,10 @@ static const BxOpcodeInfo_t opcodesGroupModINVLPG[2] = {
|
||||
};
|
||||
|
||||
static const BxOpcodeInfo_t BxOpcodeInfo64G7[8] = {
|
||||
/* 0 */ { 0, &BX_CPU_C::SGDT_Ms },
|
||||
/* 1 */ { 0, &BX_CPU_C::SIDT_Ms },
|
||||
/* 2 */ { 0, &BX_CPU_C::LGDT_Ms },
|
||||
/* 3 */ { 0, &BX_CPU_C::LIDT_Ms },
|
||||
/* 0 */ { 0, &BX_CPU_C::SGDT64_Ms },
|
||||
/* 1 */ { 0, &BX_CPU_C::SIDT64_Ms },
|
||||
/* 2 */ { 0, &BX_CPU_C::LGDT64_Ms },
|
||||
/* 3 */ { 0, &BX_CPU_C::LIDT64_Ms },
|
||||
/* 4 */ { 0, &BX_CPU_C::SMSW_Ew },
|
||||
/* 5 */ { 0, &BX_CPU_C::BxError },
|
||||
/* 6 */ { 0, &BX_CPU_C::LMSW_Ew },
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: mmx.cc,v 1.56 2007-01-25 21:44:35 sshwarts Exp $
|
||||
// $Id: mmx.cc,v 1.57 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2002 Stanislav Shwartsman
|
||||
@ -1206,7 +1206,7 @@ void BX_CPU_C::MOVD_EdPd(bxInstruction_c *i)
|
||||
{
|
||||
/* destination is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REG(i->rm(), MMXUD0(op));
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), MMXUD0(op));
|
||||
}
|
||||
else {
|
||||
write_virtual_dword(i->seg(), RMAddr(i), &(MMXUD0(op)));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: protect_ctrl.cc,v 1.54 2007-01-25 19:09:41 sshwarts Exp $
|
||||
// $Id: protect_ctrl.cc,v 1.55 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -30,8 +30,6 @@
|
||||
#include "cpu.h"
|
||||
#define LOG_THIS BX_CPU_THIS_PTR
|
||||
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
|
||||
void BX_CPU_C::ARPL_EwGw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op2_16, op1_16;
|
||||
@ -79,8 +77,6 @@ void BX_CPU_C::ARPL_EwGw(bxInstruction_c *i)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::LAR_GvEw(bxInstruction_c *i)
|
||||
{
|
||||
/* for 16 bit operand size mode */
|
||||
@ -90,7 +86,7 @@ void BX_CPU_C::LAR_GvEw(bxInstruction_c *i)
|
||||
Bit32u dword1, dword2;
|
||||
|
||||
if (real_mode() || v8086_mode()) {
|
||||
BX_INFO(("LAR: not recognized in real or virtual-8086 mode"));
|
||||
BX_ERROR(("LAR: not recognized in real or virtual-8086 mode"));
|
||||
UndefinedOpcode(i);
|
||||
return;
|
||||
}
|
||||
@ -193,7 +189,7 @@ void BX_CPU_C::LSL_GvEw(bxInstruction_c *i)
|
||||
Bit32u descriptor_dpl;
|
||||
|
||||
if (real_mode() || v8086_mode()) {
|
||||
BX_INFO(("LSL: not recognized in real or virtual-8086 mode"));
|
||||
BX_ERROR(("LSL: not recognized in real or virtual-8086 mode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
@ -237,7 +233,6 @@ void BX_CPU_C::LSL_GvEw(bxInstruction_c *i)
|
||||
return;
|
||||
}
|
||||
goto lsl_ok;
|
||||
break;
|
||||
default:
|
||||
clear_ZF();
|
||||
return;
|
||||
@ -263,51 +258,57 @@ lsl_ok:
|
||||
/* all checks pass, limit32 is now byte granular, write to op1 */
|
||||
assert_ZF();
|
||||
|
||||
if (i->os32L())
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), limit32)
|
||||
else
|
||||
if (i->os32L()) {
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), limit32);
|
||||
}
|
||||
else {
|
||||
// chop off upper 16 bits
|
||||
BX_WRITE_16BIT_REG(i->nnn(), (Bit16u) limit32)
|
||||
BX_WRITE_16BIT_REG(i->nnn(), (Bit16u) limit32);
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
|
||||
void BX_CPU_C::SLDT_Ew(bxInstruction_c *i)
|
||||
{
|
||||
if (real_mode() || v8086_mode()) {
|
||||
BX_INFO(("SLDT: not recognized in real or virtual-8086 mode"));
|
||||
BX_ERROR(("SLDT: not recognized in real or virtual-8086 mode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
Bit16u val16 = BX_CPU_THIS_PTR ldtr.selector.value;
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), val16);
|
||||
if (i->os32L()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), val16);
|
||||
}
|
||||
else {
|
||||
BX_WRITE_16BIT_REG(i->rm(), val16);
|
||||
}
|
||||
}
|
||||
else {
|
||||
write_virtual_word(i->seg(), RMAddr(i), &val16);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::STR_Ew(bxInstruction_c *i)
|
||||
{
|
||||
if (real_mode() || v8086_mode()) {
|
||||
BX_INFO(("STR: not recognized in real or virtual-8086 mode"));
|
||||
BX_ERROR(("STR: not recognized in real or virtual-8086 mode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
Bit16u val16 = BX_CPU_THIS_PTR tr.selector.value;
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_16BIT_REG(i->rm(), val16);
|
||||
if (i->os32L()) {
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), val16);
|
||||
}
|
||||
else {
|
||||
BX_WRITE_16BIT_REG(i->rm(), val16);
|
||||
}
|
||||
}
|
||||
else {
|
||||
write_virtual_word(i->seg(), RMAddr(i), &val16);
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
|
||||
void BX_CPU_C::LLDT_Ew(bxInstruction_c *i)
|
||||
{
|
||||
/* protected mode */
|
||||
@ -320,13 +321,13 @@ void BX_CPU_C::LLDT_Ew(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
if (real_mode() || v8086_mode()) {
|
||||
BX_INFO(("LTR: not recognized in real or virtual-8086 mode"));
|
||||
BX_ERROR(("LTR: not recognized in real or virtual-8086 mode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
/* #GP(0) if the current privilege level is not 0 */
|
||||
if (CPL != 0) {
|
||||
BX_INFO(("LLDT: The current priveledge level is not 0"));
|
||||
BX_ERROR(("LLDT: The current priveledge level is not 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
@ -399,7 +400,7 @@ void BX_CPU_C::LTR_Ew(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
if (real_mode() || v8086_mode()) {
|
||||
BX_INFO(("LTR: not recognized in real or virtual-8086 mode"));
|
||||
BX_ERROR(("LTR: not recognized in real or virtual-8086 mode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
@ -441,7 +442,7 @@ void BX_CPU_C::LTR_Ew(bxInstruction_c *i)
|
||||
// set upper 32 bits of tss base
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector.index*8 + 8, 4, 0, BX_READ, &dword3);
|
||||
descriptor.u.system.base |= ((Bit64u)dword3 << 32);
|
||||
BX_INFO(("64 bit tss base = 0x%08x%08x",
|
||||
BX_INFO(("64 bit TSS base = 0x%08x%08x",
|
||||
GET32H(descriptor.u.system.base), GET32L(descriptor.u.system.base)));
|
||||
}
|
||||
#endif
|
||||
@ -474,8 +475,6 @@ void BX_CPU_C::LTR_Ew(bxInstruction_c *i)
|
||||
BX_WRITE, &dword2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::VERR_Ew(bxInstruction_c *i)
|
||||
{
|
||||
/* for 16 bit operand size mode */
|
||||
@ -485,7 +484,7 @@ void BX_CPU_C::VERR_Ew(bxInstruction_c *i)
|
||||
Bit32u dword1, dword2;
|
||||
|
||||
if (real_mode() || v8086_mode()) {
|
||||
BX_INFO(("VERR: not recognized in real or virtual-8086 mode"));
|
||||
BX_ERROR(("VERR: not recognized in real or virtual-8086 mode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
@ -573,7 +572,7 @@ void BX_CPU_C::VERW_Ew(bxInstruction_c *i)
|
||||
Bit32u dword1, dword2;
|
||||
|
||||
if (real_mode() || v8086_mode()) {
|
||||
BX_INFO(("VERW: not recognized in real or virtual-8086 mode"));
|
||||
BX_ERROR(("VERW: not recognized in real or virtual-8086 mode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
@ -634,115 +633,57 @@ void BX_CPU_C::VERW_Ew(bxInstruction_c *i)
|
||||
clear_ZF(); /* not accessible */
|
||||
}
|
||||
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
|
||||
void BX_CPU_C::SGDT_Ms(bxInstruction_c *i)
|
||||
{
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_INFO(("SGDT_Ms: use of register is undefined opcode"));
|
||||
BX_ERROR(("SGDT_Ms: use of register is undefined opcode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
{
|
||||
Bit16u limit_16 = BX_CPU_THIS_PTR gdtr.limit;
|
||||
Bit64u base_64 = BX_CPU_THIS_PTR gdtr.base;
|
||||
Bit16u limit_16 = BX_CPU_THIS_PTR gdtr.limit;
|
||||
Bit32u base_32 = BX_CPU_THIS_PTR gdtr.base;
|
||||
|
||||
write_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
write_virtual_qword(i->seg(), RMAddr(i)+2, &base_64);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Bit16u limit_16 = BX_CPU_THIS_PTR gdtr.limit;
|
||||
Bit32u base_32 = BX_CPU_THIS_PTR gdtr.base;
|
||||
#if BX_CPU_LEVEL == 2
|
||||
base_32 |= 0xff000000; /* ??? */
|
||||
#else /* 386+ */
|
||||
/* 32bit processors always write 32bits of base */
|
||||
#endif
|
||||
write_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
write_virtual_dword(i->seg(), RMAddr(i)+2, &base_32);
|
||||
}
|
||||
#endif
|
||||
write_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
write_virtual_dword(i->seg(), RMAddr(i)+2, &base_32);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SIDT_Ms(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_CPU_LEVEL < 2
|
||||
BX_PANIC(("SIDT_Ms: not supported on 8086!"));
|
||||
UndefinedOpcode(i);
|
||||
#else
|
||||
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_INFO(("SIDT: use of register is undefined opcode"));
|
||||
BX_ERROR(("SIDT_Ms: use of register is undefined opcode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
{
|
||||
Bit16u limit_16 = BX_CPU_THIS_PTR idtr.limit;
|
||||
Bit64u base_64 = BX_CPU_THIS_PTR idtr.base;
|
||||
Bit16u limit_16 = BX_CPU_THIS_PTR idtr.limit;
|
||||
Bit32u base_32 = BX_CPU_THIS_PTR idtr.base;
|
||||
|
||||
write_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
write_virtual_qword(i->seg(), RMAddr(i)+2, &base_64);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Bit16u limit_16 = BX_CPU_THIS_PTR idtr.limit;
|
||||
Bit32u base_32 = BX_CPU_THIS_PTR idtr.base;
|
||||
|
||||
#if BX_CPU_LEVEL == 2
|
||||
base_32 |= 0xff000000;
|
||||
#else /* 386+ */
|
||||
/* regardless of operand size, all 32bits of base are stored */
|
||||
#endif
|
||||
|
||||
write_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
write_virtual_dword(i->seg(), RMAddr(i)+2, &base_32);
|
||||
}
|
||||
write_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
write_virtual_dword(i->seg(), RMAddr(i)+2, &base_32);
|
||||
}
|
||||
|
||||
void BX_CPU_C::LGDT_Ms(bxInstruction_c *i)
|
||||
{
|
||||
/* operand might be a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_ERROR(("LGDT: must be memory reference"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
if (v8086_mode()) {
|
||||
BX_INFO(("LGDT: not recognized in virtual-8086 mode"));
|
||||
BX_ERROR(("LGDT: not recognized in virtual-8086 mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
if (!real_mode() && CPL!=0) {
|
||||
BX_ERROR(("LGDT: CPL!=0 in protected mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
if (!real_mode() && CPL!=0) {
|
||||
BX_INFO(("LGDT: CPL!=0 in protected mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
/* operand might be a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_INFO(("LGDT: must be memory reference"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
{
|
||||
Bit16u limit_16;
|
||||
Bit64u base_64;
|
||||
|
||||
read_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
read_virtual_qword(i->seg(), RMAddr(i) + 2, &base_64);
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.limit = limit_16;
|
||||
BX_CPU_THIS_PTR gdtr.base = base_64;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (i->os32L()) {
|
||||
Bit16u limit_16;
|
||||
Bit32u base0_31;
|
||||
@ -771,41 +712,28 @@ void BX_CPU_C::LGDT_Ms(bxInstruction_c *i)
|
||||
|
||||
void BX_CPU_C::LIDT_Ms(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u limit_16;
|
||||
Bit32u base_32;
|
||||
|
||||
if (v8086_mode()) {
|
||||
BX_INFO(("LIDT: not recognized in virtual-8086 mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
/* operand might be a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_ERROR(("LIDT: must be memory reference"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
invalidate_prefetch_q();
|
||||
if (v8086_mode()) {
|
||||
BX_ERROR(("LIDT: not recognized in virtual-8086 mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
if (!real_mode() && CPL!=0) {
|
||||
BX_ERROR(("LIDT: CPL!=0 in protected mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
/* operand might be a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_INFO(("LIDT: must be memory reference"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
invalidate_prefetch_q();
|
||||
|
||||
Bit16u limit_16;
|
||||
Bit32u base_32;
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)
|
||||
{
|
||||
Bit64u base_64;
|
||||
|
||||
read_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
read_virtual_qword(i->seg(), RMAddr(i) + 2, &base_64);
|
||||
|
||||
BX_CPU_THIS_PTR idtr.limit = limit_16;
|
||||
BX_CPU_THIS_PTR idtr.base = base_64;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (i->os32L()) {
|
||||
read_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
read_virtual_dword(i->seg(), RMAddr(i) + 2, &base_32);
|
||||
@ -824,4 +752,90 @@ void BX_CPU_C::LIDT_Ms(bxInstruction_c *i)
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
|
||||
void BX_CPU_C::SGDT64_Ms(bxInstruction_c *i)
|
||||
{
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_ERROR(("SGDT64_Ms: use of register is undefined opcode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
Bit16u limit_16 = BX_CPU_THIS_PTR gdtr.limit;
|
||||
Bit64u base_64 = BX_CPU_THIS_PTR gdtr.base;
|
||||
|
||||
write_virtual_word (i->seg(), RMAddr(i), &limit_16);
|
||||
write_virtual_qword(i->seg(), RMAddr(i)+2, &base_64);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SIDT64_Ms(bxInstruction_c *i)
|
||||
{
|
||||
/* op1 is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_ERROR(("SIDT64_Ms: use of register is undefined opcode"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
Bit16u limit_16 = BX_CPU_THIS_PTR idtr.limit;
|
||||
Bit64u base_64 = BX_CPU_THIS_PTR idtr.base;
|
||||
|
||||
write_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
write_virtual_qword(i->seg(), RMAddr(i)+2, &base_64);
|
||||
}
|
||||
|
||||
void BX_CPU_C::LGDT64_Ms(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(protected_mode());
|
||||
|
||||
/* operand might be a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_ERROR(("LGDT64_Ms: must be memory reference"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
if (CPL!=0) {
|
||||
BX_ERROR(("LGDT64_Ms: CPL != 0 in long mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
Bit16u limit_16;
|
||||
Bit64u base_64;
|
||||
|
||||
read_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
read_virtual_qword(i->seg(), RMAddr(i) + 2, &base_64);
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.limit = limit_16;
|
||||
BX_CPU_THIS_PTR gdtr.base = base_64;
|
||||
}
|
||||
|
||||
void BX_CPU_C::LIDT64_Ms(bxInstruction_c *i)
|
||||
{
|
||||
BX_ASSERT(protected_mode());
|
||||
|
||||
/* operand might be a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_ERROR(("LIDT64_Ms: must be memory reference"));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
|
||||
if (CPL != 0) {
|
||||
BX_ERROR(("LIDT64_Ms: CPL != 0 in long mode"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
Bit16u limit_16;
|
||||
Bit64u base_64;
|
||||
|
||||
read_virtual_word(i->seg(), RMAddr(i), &limit_16);
|
||||
read_virtual_qword(i->seg(), RMAddr(i) + 2, &base_64);
|
||||
|
||||
BX_CPU_THIS_PTR idtr.limit = limit_16;
|
||||
BX_CPU_THIS_PTR idtr.base = base_64;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: sse_move.cc,v 1.53 2006-08-31 18:18:17 sshwarts Exp $
|
||||
// $Id: sse_move.cc,v 1.54 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2003 Stanislav Shwartsman
|
||||
@ -959,7 +959,7 @@ void BX_CPU_C::MOVD_EdVd(bxInstruction_c *i)
|
||||
|
||||
/* destination is a register or memory reference */
|
||||
if (i->modC0()) {
|
||||
BX_WRITE_32BIT_REG(i->rm(), op2);
|
||||
BX_WRITE_32BIT_REGZ(i->rm(), op2);
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: sse_pfp.cc,v 1.27 2006-04-05 17:31:33 sshwarts Exp $
|
||||
// $Id: sse_pfp.cc,v 1.28 2007-01-26 22:12:05 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2003 Stanislav Shwartsman
|
||||
@ -386,7 +386,7 @@ void BX_CPU_C::CVTTSD2SI_GdWsd(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u result = float64_to_int32_round_to_zero(op, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_32BIT_REG(i->nnn(), result);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), result);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -432,7 +432,7 @@ void BX_CPU_C::CVTTSS2SI_GdWss(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u result = float32_to_int32_round_to_zero(op, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_32BIT_REG(i->nnn(), result);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), result);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -560,7 +560,7 @@ void BX_CPU_C::CVTSD2SI_GdWsd(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u result = float64_to_int32(op, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_32BIT_REG(i->nnn(), result);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), result);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -607,7 +607,7 @@ void BX_CPU_C::CVTSS2SI_GdWss(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u result = float32_to_int32(op, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_32BIT_REG(i->nnn(), result);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), result);
|
||||
}
|
||||
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user