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