Author: aandrejevic
Date: Mon Sep 23 17:29:42 2013
New Revision: 60344
URL:
http://svn.reactos.org/svn/reactos?rev=60344&view=rev
Log:
[SOFT386]
Implement the IMUL instruction. Both versions have been implemented in
Soft386OpcodeImulModrm.
Modified:
branches/ntvdm/lib/soft386/opcodes.c
branches/ntvdm/lib/soft386/opcodes.h
Modified: branches/ntvdm/lib/soft386/opcodes.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/opcodes.c?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/opcodes.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/opcodes.c [iso-8859-1] Mon Sep 23 17:29:42 2013
@@ -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 @@
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(Soft386OpcodeImulModrmImm)
{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
+ BOOLEAN OperandSize, AddressSize;
+ SOFT386_MOD_REG_RM ModRegRm;
+ LONG Multiplier;
+ LONGLONG Product;
+
+ /* 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)
@@ -3818,14 +3934,6 @@
/* Call the internal API */
return Soft386StackPush(State, Data);
-}
-
-SOFT386_OPCODE_HANDLER(Soft386OpcodeImulModrmByteImm)
-{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
}
SOFT386_OPCODE_HANDLER(Soft386OpcodeMovByteModrm)
Modified: branches/ntvdm/lib/soft386/opcodes.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/opcodes.h?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/opcodes.h [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/opcodes.h [iso-8859-1] Mon Sep 23 17:29:42 2013
@@ -101,7 +101,6 @@
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);