Performance mod: I implemented a suggestion from Peter Tattam
and Jas Sandys-Lumsdaine to split out common instructions into variants which deal with the mod=11b case (Reg-Reg) and the other cases (which do memory ops). Actually, I only split MOV_GwEw and MOV_GdEd for now. According to some instrumentation of a Win95 boot, they were the most frequently used opcode by far.
This commit is contained in:
parent
935b0f97bd
commit
08a89fe7b6
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.85 2002-09-28 00:54:04 kevinlawton Exp $
|
||||
// $Id: cpu.h,v 1.86 2002-09-28 05:38:11 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1649,8 +1649,15 @@ union {
|
||||
BX_SMF void MOV_EdGd(bxInstruction_c *);
|
||||
BX_SMF void MOV_EwGw(bxInstruction_c *);
|
||||
BX_SMF void MOV_GbEb(bxInstruction_c *);
|
||||
|
||||
BX_SMF void MOV_GdEd(bxInstruction_c *);
|
||||
BX_SMF void MOV_GdEGd(bxInstruction_c *);
|
||||
BX_SMF void MOV_GdEEd(bxInstruction_c *);
|
||||
|
||||
BX_SMF void MOV_GwEw(bxInstruction_c *);
|
||||
BX_SMF void MOV_GwEGw(bxInstruction_c *);
|
||||
BX_SMF void MOV_GwEEw(bxInstruction_c *);
|
||||
|
||||
BX_SMF void MOV_EwSw(bxInstruction_c *);
|
||||
BX_SMF void LEA_GdM(bxInstruction_c *);
|
||||
BX_SMF void LEA_GwM(bxInstruction_c *);
|
||||
@ -2956,6 +2963,7 @@ IMPLEMENT_EFLAG_ACCESSOR (TF, 8)
|
||||
|
||||
#define BxPrefix 0x0010 // bit 4
|
||||
#define BxAnother 0x0020 // bit 5
|
||||
#define SplitMod11b 0x0040 // bit 6
|
||||
#define BxRepeatable 0x0800 // bit 11 (pass through to metaInfo field)
|
||||
#define BxRepeatableZF 0x1000 // bit 12 (pass through to metaInfo field)
|
||||
#define BxGroupN 0x0100 // bits 8
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: data_xfer16.cc,v 1.15 2002-09-22 18:22:24 kevinlawton Exp $
|
||||
// $Id: data_xfer16.cc,v 1.16 2002-09-28 05:38:11 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -71,19 +71,23 @@ BX_CPU_C::MOV_EwGw(bxInstruction_c *i)
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::MOV_GwEw(bxInstruction_c *i)
|
||||
BX_CPU_C::MOV_GwEGw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u op2_16;
|
||||
// 2nd modRM operand Ex, is known to be a general register Gw.
|
||||
Bit16u op2_16;
|
||||
|
||||
if (i->modC0()) {
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
}
|
||||
op2_16 = BX_READ_16BIT_REG(i->rm());
|
||||
BX_WRITE_16BIT_REG(i->nnn(), op2_16);
|
||||
}
|
||||
|
||||
BX_WRITE_16BIT_REG(i->nnn(), op2_16);
|
||||
void
|
||||
BX_CPU_C::MOV_GwEEw(bxInstruction_c *i)
|
||||
{
|
||||
// 2nd modRM operand Ex, is known to be a memory operand, Ew.
|
||||
Bit16u op2_16;
|
||||
|
||||
read_virtual_word(i->seg(), RMAddr(i), &op2_16);
|
||||
BX_WRITE_16BIT_REG(i->nnn(), op2_16);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: data_xfer32.cc,v 1.16 2002-09-22 18:22:24 kevinlawton Exp $
|
||||
// $Id: data_xfer32.cc,v 1.17 2002-09-28 05:38:11 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -80,21 +80,24 @@ BX_CPU_C::MOV_EdGd(bxInstruction_c *i)
|
||||
|
||||
|
||||
void
|
||||
BX_CPU_C::MOV_GdEd(bxInstruction_c *i)
|
||||
BX_CPU_C::MOV_GdEGd(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u op2_32;
|
||||
// 2nd modRM operand Ex, is known to be a general register Gd.
|
||||
Bit32u op2_32;
|
||||
|
||||
if (i->modC0()) {
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
}
|
||||
else {
|
||||
/* pointer, segment address pair */
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
|
||||
}
|
||||
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op2_32);
|
||||
op2_32 = BX_READ_32BIT_REG(i->rm());
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op2_32);
|
||||
}
|
||||
|
||||
void
|
||||
BX_CPU_C::MOV_GdEEd(bxInstruction_c *i)
|
||||
{
|
||||
// 2nd modRM operand Ex, is known to be a memory operand, Ed.
|
||||
Bit32u op2_32;
|
||||
|
||||
read_virtual_dword(i->seg(), RMAddr(i), &op2_32);
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), op2_32);
|
||||
}
|
||||
|
||||
void
|
||||
BX_CPU_C::LEA_GdM(bxInstruction_c *i)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.cc,v 1.23 2002-09-28 00:54:04 kevinlawton Exp $
|
||||
// $Id: fetchdecode.cc,v 1.24 2002-09-28 05:38:11 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -344,6 +344,16 @@ static BxOpcodeInfo_t BxOpcodeInfoG9[8] = {
|
||||
/* 7 */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GwEw[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GwEEw },
|
||||
{ 0, &BX_CPU_C::MOV_GwEGw }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t opcodesMOV_GdEd[2] = {
|
||||
{ 0, &BX_CPU_C::MOV_GdEEd },
|
||||
{ 0, &BX_CPU_C::MOV_GdEGd }
|
||||
};
|
||||
|
||||
#if BX_SUPPORT_MMX
|
||||
static BxOpcodeInfo_t BxOpcodeInfoGAw[8] = { /* MMX */
|
||||
/* 0 */ { 0, &BX_CPU_C::BxError },
|
||||
@ -523,7 +533,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
|
||||
/* 88 */ { BxAnother, &BX_CPU_C::MOV_EbGb },
|
||||
/* 89 */ { BxAnother, &BX_CPU_C::MOV_EwGw },
|
||||
/* 8A */ { BxAnother, &BX_CPU_C::MOV_GbEb },
|
||||
/* 8B */ { BxAnother, &BX_CPU_C::MOV_GwEw },
|
||||
/* 8B */ { BxAnother | SplitMod11b, (BxExecutePtr_t)opcodesMOV_GwEw },
|
||||
/* 8C */ { BxAnother, &BX_CPU_C::MOV_EwSw },
|
||||
/* 8D */ { BxAnother, &BX_CPU_C::LEA_GwM },
|
||||
/* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
|
||||
@ -1052,7 +1062,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
|
||||
/* 88 */ { BxAnother, &BX_CPU_C::MOV_EbGb },
|
||||
/* 89 */ { BxAnother, &BX_CPU_C::MOV_EdGd },
|
||||
/* 8A */ { BxAnother, &BX_CPU_C::MOV_GbEb },
|
||||
/* 8B */ { BxAnother, &BX_CPU_C::MOV_GdEd },
|
||||
/* 8B */ { BxAnother | SplitMod11b, (BxExecutePtr_t)opcodesMOV_GdEd },
|
||||
/* 8C */ { BxAnother, &BX_CPU_C::MOV_EwSw },
|
||||
/* 8D */ { BxAnother, &BX_CPU_C::LEA_GdM },
|
||||
/* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
|
||||
@ -1847,6 +1857,14 @@ modrm_done:
|
||||
instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
|
||||
instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
|
||||
#endif
|
||||
// For high frequency opcodes, two variants of the instruction are
|
||||
// implemented; one for the mod=11b case (Reg-Reg), and one for
|
||||
// the other cases (Reg-Mem).
|
||||
if (attr & SplitMod11b) {
|
||||
BxOpcodeInfo_t *OpcodeInfoPtr;
|
||||
OpcodeInfoPtr = (BxOpcodeInfo_t *) instruction->execute;
|
||||
instruction->execute = OpcodeInfoPtr[mod==0xc0].ExecutePtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user