Implemented MOVD 64bit extensions

This commit is contained in:
Stanislav Shwartsman 2003-01-08 20:33:28 +00:00
parent 3fdba77f4e
commit e6eacd984f
2 changed files with 111 additions and 33 deletions

View File

@ -490,16 +490,34 @@ void BX_CPU_C::MOVD_PqEd(bxInstruction_c *i)
BX_CPU_THIS_PTR prepareMMX(); BX_CPU_THIS_PTR prepareMMX();
BxPackedMmxRegister op; BxPackedMmxRegister op;
MMXUD1(op) = 0;
/* op is a register or memory reference */ #if BX_SUPPORT_X86_64
if (i->modC0()) { if (i->os64L()) /* 64 bit operand size mode */
MMXUD0(op) = BX_READ_32BIT_REG(i->rm()); {
/* op is a register or memory reference */
if (i->modC0()) {
MMXUQ(op) = BX_READ_64BIT_REG(i->rm());
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg(), RMAddr(i), &(MMXUQ(op)));
}
} }
else { else
/* pointer, segment address pair */ #else
read_virtual_dword(i->seg(), RMAddr(i), &(MMXUD0(op))); {
MMXUD1(op) = 0;
/* op is a register or memory reference */
if (i->modC0()) {
MMXUD0(op) = BX_READ_32BIT_REG(i->rm());
}
else {
/* pointer, segment address pair */
read_virtual_dword(i->seg(), RMAddr(i), &(MMXUD0(op)));
}
} }
#endif
/* now write result back to destination */ /* now write result back to destination */
BX_WRITE_MMX_REG(i->nnn(), op); BX_WRITE_MMX_REG(i->nnn(), op);
@ -686,13 +704,30 @@ void BX_CPU_C::MOVD_EdPd(bxInstruction_c *i)
BxPackedMmxRegister op = BX_READ_MMX_REG(i->nnn()); BxPackedMmxRegister op = BX_READ_MMX_REG(i->nnn());
/* destination is a register or memory reference */ #if BX_SUPPORT_X86_64
if (i->modC0()) { if (i->os64L()) /* 64 bit operand size mode */
BX_WRITE_32BIT_REG(i->rm(), MMXUD0(op)); {
/* destination is a register or memory reference */
if (i->modC0()) {
BX_WRITE_64BIT_REG(i->rm(), MMXUQ(op));
}
else {
write_virtual_qword(i->seg(), RMAddr(i), &(MMXUQ(op)));
}
} }
else { else
write_virtual_dword(i->seg(), RMAddr(i), &(MMXUD0(op))); #else
{
/* destination is a register or memory reference */
if (i->modC0()) {
BX_WRITE_32BIT_REG(i->rm(), MMXUD0(op));
}
else {
write_virtual_dword(i->seg(), RMAddr(i), &(MMXUD0(op)));
}
} }
#endif
#else #else
BX_INFO(("MOVD_EdPd: MMX not supported in current configuration")); BX_INFO(("MOVD_EdPd: MMX not supported in current configuration"));
UndefinedOpcode(i); UndefinedOpcode(i);

View File

@ -687,23 +687,45 @@ void BX_CPU_C::MOVD_VdqEd(bxInstruction_c *i)
#if BX_SUPPORT_SSE >= 2 #if BX_SUPPORT_SSE >= 2
BX_CPU_THIS_PTR prepareSSE(); BX_CPU_THIS_PTR prepareSSE();
BxPackedXmmRegister op; BxPackedXmmRegister op1;
Bit32u val32; op1.xmm64u(1) = 0;
/* val32 is a register or memory reference */ #if BX_SUPPORT_X86_64
if (i->modC0()) { if (i->os64L()) /* 64 bit operand size mode */
val32 = BX_READ_32BIT_REG(i->rm()); {
} Bit64u op2;
else {
/* pointer, segment address pair */
read_virtual_dword(i->seg(), RMAddr(i), &val32);
}
op.xmm64u(1) = 0; /* op2 is a register or memory reference */
op.xmm64u(0) = (Bit64u)(val32); if (i->modC0()) {
op2 = BX_READ_64BIT_REG(i->rm());
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg(), RMAddr(i), &op2);
}
op1.xmm64u(0) = op2;
}
else
#else
{
Bit32u op2;
/* op2 is a register or memory reference */
if (i->modC0()) {
op2 = BX_READ_32BIT_REG(i->rm());
}
else {
/* pointer, segment address pair */
read_virtual_dword(i->seg(), RMAddr(i), &op2);
}
op1.xmm64u(0) = (Bit64u)(op2);
}
#endif
/* now write result back to destination */ /* now write result back to destination */
BX_WRITE_XMM_REG(i->nnn(), op); BX_WRITE_XMM_REG(i->nnn(), op1);
#else #else
BX_INFO(("MOVD_VdqEd: SSE2 not supported in current configuration")); BX_INFO(("MOVD_VdqEd: SSE2 not supported in current configuration"));
UndefinedOpcode(i); UndefinedOpcode(i);
@ -716,17 +738,38 @@ void BX_CPU_C::MOVD_EdVd(bxInstruction_c *i)
#if BX_SUPPORT_SSE >= 2 #if BX_SUPPORT_SSE >= 2
BX_CPU_THIS_PTR prepareSSE(); BX_CPU_THIS_PTR prepareSSE();
BxPackedXmmRegister op = BX_READ_XMM_REG(i->nnn()); BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn());
Bit32u val32 = op.xmm32u(0);
/* destination is a register or memory reference */ #if BX_SUPPORT_X86_64
if (i->modC0()) { if (i->os64L()) /* 64 bit operand size mode */
BX_WRITE_32BIT_REG(i->rm(), val32); {
} Bit64u op2 = op1.xmm64u(0);
else {
write_virtual_dword(i->seg(), RMAddr(i), &val32); /* destination is a register or memory reference */
if (i->modC0()) {
BX_WRITE_64BIT_REG(i->rm(), op2);
}
else {
/* pointer, segment address pair */
write_virtual_qword(i->seg(), RMAddr(i), &op2);
}
} }
else
#else #else
{
Bit32u op2 = op1.xmm32u(0);
/* destination is a register or memory reference */
if (i->modC0()) {
BX_WRITE_32BIT_REG(i->rm(), op2);
}
else {
/* pointer, segment address pair */
write_virtual_dword(i->seg(), RMAddr(i), &op2);
}
}
#endif
BX_INFO(("MOVD_EdVd: SSE2 not supported in current configuration")); BX_INFO(("MOVD_EdVd: SSE2 not supported in current configuration"));
UndefinedOpcode(i); UndefinedOpcode(i);
#endif #endif