From 0aed89f779ebb0b6bbf0aa8c462c9d0394af2235 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Tue, 12 Nov 2013 18:21:30 +0000 Subject: [PATCH] [FAST486] Fix the 3-byte IMUL instruction. If the operand size is 16-bit, the result should be written in 16-bit too. svn path=/branches/ntvdm/; revision=60963 --- lib/fast486/opcodes.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/fast486/opcodes.c b/lib/fast486/opcodes.c index 07e870c96da..518211c762e 100644 --- a/lib/fast486/opcodes.c +++ b/lib/fast486/opcodes.c @@ -3595,7 +3595,6 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm) BOOLEAN OperandSize, AddressSize; FAST486_MOD_REG_RM ModRegRm; LONG Multiplier; - LONGLONG Product; /* Make sure this is the right instruction */ ASSERT((Opcode & 0xFD) == 0x69); @@ -3658,6 +3657,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm) if (OperandSize) { LONG RegValue, Multiplicand; + LONGLONG Product; /* Read the operands */ if (!Fast486ReadModrmDwordOperands(State, @@ -3671,10 +3671,20 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm) /* Multiply */ Product = (LONGLONG)Multiplicand * (LONGLONG)Multiplier; + + /* Check for carry/overflow */ + State->Flags.Cf = State->Flags.Of = ((Product < MINLONG) || (Product > MAXLONG)); + + /* Write-back the result */ + return Fast486WriteModrmDwordOperands(State, + &ModRegRm, + TRUE, + (ULONG)((LONG)Product)); } else { SHORT RegValue, Multiplicand; + LONG Product; /* Read the operands */ if (!Fast486ReadModrmWordOperands(State, @@ -3687,17 +3697,17 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeImulModrmImm) } /* Multiply */ - Product = (LONGLONG)Multiplicand * (LONGLONG)Multiplier; + Product = (LONG)Multiplicand * (LONG)Multiplier; + + /* Check for carry/overflow */ + State->Flags.Cf = State->Flags.Of = ((Product < MINSHORT) || (Product > MAXSHORT)); + + /* Write-back the result */ + return Fast486WriteModrmWordOperands(State, + &ModRegRm, + TRUE, + (USHORT)((SHORT)Product)); } - - /* Check for carry/overflow */ - State->Flags.Cf = State->Flags.Of = ((Product < MINLONG) || (Product > MAXLONG)); - - /* Write-back the result */ - return Fast486WriteModrmDwordOperands(State, - &ModRegRm, - TRUE, - (ULONG)((LONG)Product)); } FAST486_OPCODE_HANDLER(Fast486OpcodePushByteImm)