Fixes in zero upper ECX
This commit is contained in:
parent
6b86091441
commit
e812f81e7b
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.cc,v 1.172 2007-07-09 15:16:10 sshwarts Exp $
|
||||
// $Id: cpu.cc,v 1.173 2007-09-25 16:11:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -116,6 +116,7 @@ static unsigned iCacheMisses=0;
|
||||
#if BX_SUPPORT_X86_64==0
|
||||
#define RIP EIP
|
||||
#define RSP ESP
|
||||
#define RCX ECX
|
||||
#endif
|
||||
|
||||
BX_CPP_INLINE bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_address eipBiased)
|
||||
@ -330,7 +331,7 @@ void BX_CPU_C::repeat(bxInstruction_c *i, BxExecutePtr_t execute)
|
||||
if (ECX != 0) {
|
||||
BX_CPU_CALL_METHOD(execute, (i));
|
||||
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
|
||||
ECX --;
|
||||
RCX = ECX - 1;
|
||||
}
|
||||
if (ECX == 0) return;
|
||||
}
|
||||
@ -381,7 +382,7 @@ void BX_CPU_C::repeat_ZFL(bxInstruction_c *i, BxExecutePtr_t execute)
|
||||
if (ECX != 0) {
|
||||
BX_CPU_CALL_METHOD(execute, (i));
|
||||
BX_INSTR_REPEAT_ITERATION(BX_CPU_ID, i);
|
||||
ECX --;
|
||||
RCX = ECX - 1;
|
||||
}
|
||||
if ((i->repUsedValue()==3) && (get_ZF()==0)) return;
|
||||
if ((i->repUsedValue()==2) && (get_ZF()!=0)) return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ctrl_xfer64.cc,v 1.47 2006-06-09 22:29:06 sshwarts Exp $
|
||||
// $Id: ctrl_xfer64.cc,v 1.48 2007-09-25 16:11:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -330,7 +330,8 @@ void BX_CPU_C::LOOPNE64_Jb(bxInstruction_c *i)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (((--ECX) != 0) && (get_ZF()==0)) {
|
||||
RCX = ECX - 1;
|
||||
if (RCX != 0 && (get_ZF()==0)) {
|
||||
branch_near64(i);
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, RIP);
|
||||
return;
|
||||
@ -343,14 +344,15 @@ void BX_CPU_C::LOOPNE64_Jb(bxInstruction_c *i)
|
||||
void BX_CPU_C::LOOPE64_Jb(bxInstruction_c *i)
|
||||
{
|
||||
if (i->as64L()) {
|
||||
if (((--RCX)!=0) && (get_ZF())) {
|
||||
if (((--RCX)!=0) && get_ZF()) {
|
||||
branch_near64(i);
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, RIP);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (((--ECX)!=0) && get_ZF()) {
|
||||
RCX = ECX - 1;
|
||||
if (RCX != 0 && get_ZF()) {
|
||||
branch_near64(i);
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, RIP);
|
||||
return;
|
||||
@ -370,7 +372,8 @@ void BX_CPU_C::LOOP64_Jb(bxInstruction_c *i)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((--ECX) != 0) {
|
||||
RCX = ECX - 1;
|
||||
if (RCX != 0) {
|
||||
branch_near64(i);
|
||||
BX_INSTR_CNEAR_BRANCH_TAKEN(BX_CPU_ID, RIP);
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ctrl_xfer_pro.cc,v 1.57 2007-09-10 20:47:08 sshwarts Exp $
|
||||
// $Id: ctrl_xfer_pro.cc,v 1.58 2007-09-25 16:11:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -49,8 +49,7 @@ void BX_CPU_C::check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (descriptor->u.segment.l)
|
||||
{
|
||||
if (descriptor->u.segment.l) {
|
||||
if (! BX_CPU_THIS_PTR efer.lma) {
|
||||
BX_PANIC(("check_cs: attempt to jump to long mode without enabling EFER.LMA !"));
|
||||
}
|
||||
@ -111,8 +110,11 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
|
||||
loadSRegLMNominal(BX_SEG_REG_CS, selector->value, cpl);
|
||||
}
|
||||
else {
|
||||
BX_DEBUG(("Compatibility Mode Activated"));
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_COMPAT;
|
||||
BX_DEBUG(("Compatibility Mode Activated"));
|
||||
if (BX_CPU_THIS_PTR dword.rip_upper != 0) {
|
||||
BX_PANIC(("handleCpuModeChange: leaving long mode with RIP upper != 0 !"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -178,8 +180,7 @@ void BX_CPU_C::branch_far64(bx_selector_t *selector,
|
||||
bx_descriptor_t *descriptor, bx_address rip, Bit8u cpl)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (descriptor->u.segment.l)
|
||||
{
|
||||
if (descriptor->u.segment.l) {
|
||||
if (! IsCanonical(rip)) {
|
||||
BX_ERROR(("branch_far: canonical RIP violation"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: io.cc,v 1.38 2007-07-09 15:16:12 sshwarts Exp $
|
||||
// $Id: io.cc,v 1.39 2007-09-25 16:11:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -423,9 +423,9 @@ void BX_CPU_C::INSW_YwDX(bxInstruction_c *i)
|
||||
else
|
||||
#endif
|
||||
if (i->as32L())
|
||||
ECX -= (wordCount-1);
|
||||
RCX = ECX - (wordCount-1);
|
||||
else
|
||||
CX -= (wordCount-1);
|
||||
CX -= (wordCount-1);
|
||||
|
||||
incr = wordCount << 1; // count * 2.
|
||||
goto doIncr;
|
||||
@ -658,9 +658,9 @@ void BX_CPU_C::OUTSW_DXXw(bxInstruction_c *i)
|
||||
else
|
||||
#endif
|
||||
if (i->as32L())
|
||||
ECX -= (wordCount-1);
|
||||
RCX = ECX - (wordCount-1);
|
||||
else
|
||||
CX -= (wordCount-1);
|
||||
CX -= (wordCount-1);
|
||||
incr = wordCount << 1; // count * 2.
|
||||
goto doIncr;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.169 2007-09-20 17:33:35 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.170 2007-09-25 16:11:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1223,6 +1223,9 @@ void BX_CPU_C::handleCpuModeChange(void)
|
||||
}
|
||||
else {
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_COMPAT;
|
||||
if (BX_CPU_THIS_PTR dword.rip_upper != 0) {
|
||||
BX_PANIC(("handleCpuModeChange: leaving long mode with RIP upper != 0 !"));
|
||||
}
|
||||
BX_DEBUG(("Compatibility Mode Activated"));
|
||||
}
|
||||
}
|
||||
@ -1309,6 +1312,10 @@ void BX_CPU_C::SetCR0(Bit32u val_32)
|
||||
}
|
||||
}
|
||||
else if (prev_pg==1 && ! BX_CPU_THIS_PTR cr0.get_PG()) {
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
|
||||
BX_ERROR(("SetCR0: attempt to leave 64 bit mode directly to legacy mode !"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
if (BX_CPU_THIS_PTR efer.lma) {
|
||||
if (BX_CPU_THIS_PTR dword.rip_upper != 0) {
|
||||
BX_PANIC(("SetCR0: attempt to leave x86-64 LONG mode with RIP upper != 0 !!!"));
|
||||
@ -1433,8 +1440,8 @@ void BX_CPU_C::RDPMC(bxInstruction_c *i)
|
||||
// writes. Misaligned etc... But to monitor bochs, this
|
||||
// is easier done from the host.
|
||||
|
||||
EAX = 0;
|
||||
EDX = 0; // if P4 and ECX & 0x10000000, then always 0 (short read 32 bits)
|
||||
RAX = 0;
|
||||
RDX = 0; // if P4 and ECX & 0x10000000, then always 0 (short read 32 bits)
|
||||
|
||||
BX_ERROR(("RDPMC: Performance Counters Support not reasonably implemented yet"));
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: protect_ctrl.cc,v 1.58 2007-03-23 14:50:45 sshwarts Exp $
|
||||
// $Id: protect_ctrl.cc,v 1.59 2007-09-25 16:11:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -452,6 +452,13 @@ void BX_CPU_C::LTR_Ew(bxInstruction_c *i)
|
||||
exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0);
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long_mode() && descriptor.type!=BX_SYS_SEGMENT_AVAIL_386_TSS) {
|
||||
BX_ERROR(("LTR: doesn't point to an available TSS386 descriptor in long mode!"));
|
||||
exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* #NP(selector) if TSS descriptor is not present */
|
||||
if (! IS_PRESENT(descriptor)) {
|
||||
BX_ERROR(("LTR: LDT descriptor not present!"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ret_far.cc,v 1.9 2007-02-03 21:36:40 sshwarts Exp $
|
||||
// $Id: ret_far.cc,v 1.10 2007-09-25 16:11:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -68,13 +68,8 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->os64L()) {
|
||||
/* operand size=64: 2nd qword on stack must be within stack limits,
|
||||
* else #SS(0); */
|
||||
if (!can_pop(16))
|
||||
{
|
||||
BX_ERROR(("return_protected: 2rd qword not in stack limits"));
|
||||
exception(BX_SS_EXCEPTION, 0, 0);
|
||||
}
|
||||
/* operand size=64: in long mode 1st and 2nd quadword on the stack
|
||||
must be in canonical address space */
|
||||
|
||||
read_virtual_word (BX_SEG_REG_SS, temp_RSP + 8, &raw_cs_selector);
|
||||
read_virtual_qword(BX_SEG_REG_SS, temp_RSP + 0, &return_RIP);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: segment_ctrl_pro.cc,v 1.70 2007-09-10 20:47:08 sshwarts Exp $
|
||||
// $Id: segment_ctrl_pro.cc,v 1.71 2007-09-25 16:11:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -38,10 +38,16 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
{
|
||||
if (seg == &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS])
|
||||
{
|
||||
bx_selector_t ss_selector;
|
||||
bx_descriptor_t descriptor;
|
||||
Bit32u dword1, dword2;
|
||||
|
||||
parse_selector(new_value, &ss_selector);
|
||||
|
||||
if ((new_value & 0xfffc) == 0) { /* null selector */
|
||||
#if BX_SUPPORT_X86_64
|
||||
// allow SS = 0 in 64 bit mode with cpl != 3
|
||||
if (BX_CPU_THIS_PTR efer.lma && CPL != 3) {
|
||||
// allow SS = 0 in 64 bit mode only with cpl != 3 and rpl=cpl
|
||||
if (Is64BitMode() && CPL != 3 && ss_selector.rpl == CPL) {
|
||||
seg->selector.index = 0;
|
||||
seg->selector.ti = 0;
|
||||
seg->selector.rpl = 0;
|
||||
@ -50,15 +56,10 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
BX_ERROR(("load_seg_reg(SS): new_value == 0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
BX_ERROR(("load_seg_reg(SS): loading null selector"));
|
||||
exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
|
||||
}
|
||||
|
||||
bx_descriptor_t descriptor;
|
||||
Bit32u dword1, dword2;
|
||||
bx_selector_t ss_selector;
|
||||
|
||||
parse_selector(new_value, &ss_selector);
|
||||
fetch_raw_descriptor(&ss_selector, &dword1, &dword2, BX_GP_EXCEPTION);
|
||||
|
||||
/* selector's RPL must = CPL, else #GP(selector) */
|
||||
@ -257,7 +258,7 @@ void BX_CPU_C::loadSRegLMNominal(unsigned segI, unsigned selector, unsigned dpl)
|
||||
// of type bx_addr and be maxed to 64bits, not 32.
|
||||
seg->cache.u.segment.limit_scaled = 0xffffffff;
|
||||
seg->cache.valid = 1;
|
||||
seg->cache.dpl = dpl; // (KPL) Not sure if we need this.
|
||||
seg->cache.dpl = dpl;
|
||||
|
||||
seg->selector.value = selector;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: string.cc,v 1.37 2007-07-09 15:16:14 sshwarts Exp $
|
||||
// $Id: string.cc,v 1.38 2007-09-25 16:11:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1049,7 +1049,7 @@ void BX_CPU_C::MOVSD_XdYd(bxInstruction_c *i)
|
||||
|
||||
// Decrement eCX. Note, the main loop will decrement 1 also, so
|
||||
// decrement by one less than expected, like the case above.
|
||||
ECX -= (dwordCount-1);
|
||||
RCX = ECX - (dwordCount-1);
|
||||
|
||||
incr = dwordCount << 2; // count * 4
|
||||
goto doIncr32;
|
||||
@ -1843,9 +1843,9 @@ void BX_CPU_C::STOSB_YbAL(bxInstruction_c *i)
|
||||
// Decrement eCX. Note, the main loop will decrement 1 also, so
|
||||
// decrement by one less than expected, like the case above.
|
||||
if (i->as32L())
|
||||
ECX -= (byteCount-1);
|
||||
RCX = ECX - (byteCount-1);
|
||||
else
|
||||
CX -= (byteCount-1);
|
||||
CX -= (byteCount-1);
|
||||
|
||||
incr = byteCount;
|
||||
goto doIncr16;
|
||||
|
Loading…
Reference in New Issue
Block a user