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:
Kevin Lawton 2002-09-28 05:38:11 +00:00
parent 935b0f97bd
commit 08a89fe7b6
4 changed files with 60 additions and 27 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;
}
}
}