mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 19:11:55 +00:00
[SOFT386]
Implement the IMUL instruction. Both versions have been implemented in Soft386OpcodeImulModrm. svn path=/branches/ntvdm/; revision=60344
This commit is contained in:
parent
442b56b45b
commit
597a77ed3c
2 changed files with 120 additions and 13 deletions
|
@ -11,6 +11,7 @@
|
|||
// #define WIN32_NO_STATUS
|
||||
// #define _INC_WINDOWS
|
||||
#include <windef.h>
|
||||
#include <limits.h>
|
||||
|
||||
// #define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -131,7 +132,7 @@ Soft386OpcodeHandlers[SOFT386_NUM_OPCODE_HANDLERS] =
|
|||
Soft386OpcodePushImm,
|
||||
Soft386OpcodeImulModrmImm,
|
||||
Soft386OpcodePushByteImm,
|
||||
Soft386OpcodeImulModrmByteImm,
|
||||
Soft386OpcodeImulModrmImm,
|
||||
NULL, // TODO: OPCODE 0x6C NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x6D NOT SUPPORTED
|
||||
NULL, // TODO: OPCODE 0x6E NOT SUPPORTED
|
||||
|
@ -3797,10 +3798,125 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodePushImm)
|
|||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeImulModrmImm)
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
SOFT386_MOD_REG_RM ModRegRm;
|
||||
LONG Multiplier;
|
||||
LONGLONG Product;
|
||||
|
||||
return FALSE;
|
||||
/* Make sure this is the right instruction */
|
||||
ASSERT((Opcode & 0xFD) == 0x69);
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
|
||||
{
|
||||
/* The ADSIZE prefix toggles the address size */
|
||||
AddressSize = !AddressSize;
|
||||
}
|
||||
|
||||
if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
|
||||
{
|
||||
/* The OPSIZE prefix toggles the operand size */
|
||||
OperandSize = !OperandSize;
|
||||
}
|
||||
|
||||
/* Fetch the parameters */
|
||||
if (!Soft386ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Opcode == 0x6B)
|
||||
{
|
||||
CHAR Byte;
|
||||
|
||||
/* Fetch the immediate operand */
|
||||
if (!Soft386FetchByte(State, (PUCHAR)&Byte))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Multiplier = (LONG)Byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OperandSize)
|
||||
{
|
||||
LONG Dword;
|
||||
|
||||
/* Fetch the immediate operand */
|
||||
if (!Soft386FetchDword(State, (PULONG)&Dword))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Multiplier = Dword;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHORT Word;
|
||||
|
||||
/* Fetch the immediate operand */
|
||||
if (!Soft386FetchWord(State, (PUSHORT)&Word))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Multiplier = (LONG)Word;
|
||||
}
|
||||
}
|
||||
|
||||
if (OperandSize)
|
||||
{
|
||||
LONG RegValue, Multiplicand;
|
||||
|
||||
/* Read the operands */
|
||||
if (!Soft386ReadModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
(PULONG)&RegValue,
|
||||
(PULONG)&Multiplicand))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Multiply */
|
||||
Product = (LONGLONG)Multiplicand * (LONGLONG)Multiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHORT RegValue, Multiplicand;
|
||||
|
||||
/* Read the operands */
|
||||
if (!Soft386ReadModrmWordOperands(State,
|
||||
&ModRegRm,
|
||||
(PUSHORT)&RegValue,
|
||||
(PUSHORT)&Multiplicand))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Multiply */
|
||||
Product = (LONGLONG)Multiplicand * (LONGLONG)Multiplier;
|
||||
}
|
||||
|
||||
/* Check for carry/overflow */
|
||||
if ((Product < LONG_MIN) || (Product > LONG_MAX))
|
||||
{
|
||||
State->Flags.Cf = State->Flags.Of = TRUE;
|
||||
}
|
||||
else State->Flags.Cf = State->Flags.Of = FALSE;
|
||||
|
||||
/* Write-back the result */
|
||||
return Soft386WriteModrmDwordOperands(State,
|
||||
&ModRegRm,
|
||||
TRUE,
|
||||
(ULONG)((LONG)Product));
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodePushByteImm)
|
||||
|
@ -3820,14 +3936,6 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodePushByteImm)
|
|||
return Soft386StackPush(State, Data);
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeImulModrmByteImm)
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovByteModrm)
|
||||
{
|
||||
UCHAR FirstValue, SecondValue, Result;
|
||||
|
|
|
@ -101,7 +101,6 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeArpl);
|
|||
SOFT386_OPCODE_HANDLER(Soft386OpcodePushImm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeImulModrmImm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodePushByteImm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeImulModrmByteImm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovByteModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovModrm);
|
||||
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovStoreSeg);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue