Author: aandrejevic
Date: Mon Nov 11 00:57:59 2013
New Revision: 60930
URL:
http://svn.reactos.org/svn/reactos?rev=60930&view=rev
Log:
[FAST486]
Implement SHLD and SHRD.
Modified:
branches/ntvdm/lib/fast486/extraops.c
branches/ntvdm/lib/fast486/extraops.h
Modified: branches/ntvdm/lib/fast486/extraops.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/extraops.c?re…
==============================================================================
--- branches/ntvdm/lib/fast486/extraops.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/extraops.c [iso-8859-1] Mon Nov 11 00:57:59 2013
@@ -201,16 +201,16 @@
Fast486ExtOpcodePopFs,
NULL, // Invalid
Fast486ExtOpcodeBitTest,
- NULL, // TODO: OPCODE 0xA4 NOT IMPLEMENTED
- NULL, // TODO: OPCODE 0xA5 NOT IMPLEMENTED
+ Fast486ExtOpcodeShld,
+ Fast486ExtOpcodeShld,
NULL, // Invalid
NULL, // Invalid
Fast486ExtOpcodePushGs,
Fast486ExtOpcodePopGs,
NULL, // Invalid
Fast486ExtOpcodeBts,
- NULL, // TODO: OPCODE 0xAC NOT IMPLEMENTED
- NULL, // TODO: OPCODE 0xAD NOT IMPLEMENTED
+ Fast486ExtOpcodeShrd,
+ Fast486ExtOpcodeShrd,
NULL, // TODO: OPCODE 0xAE NOT IMPLEMENTED
Fast486ExtOpcodeImul,
Fast486ExtOpcodeCmpXchgByte,
@@ -601,6 +601,98 @@
return TRUE;
}
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeShld)
+{
+ BOOLEAN OperandSize, AddressSize;
+ FAST486_MOD_REG_RM ModRegRm;
+ UCHAR Count;
+
+ OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ TOGGLE_OPSIZE(OperandSize);
+ TOGGLE_ADSIZE(AddressSize);
+
+ /* Make sure this is the right instruction */
+ ASSERT((Opcode & 0xFE) == 0xA4);
+
+ /* Get the operands */
+ if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ if (Opcode == 0xA4)
+ {
+ /* Fetch the count */
+ if (!Fast486FetchByte(State, &Count))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* The count is in CL */
+ Count = State->GeneralRegs[FAST486_REG_ECX].LowByte;
+ }
+
+ /* Normalize the count */
+ if (OperandSize) Count &= 0x1F;
+ else Count &= 0x0F;
+
+ /* Do nothing if the count is zero */
+ if (Count == 0) return TRUE;
+
+ if (OperandSize)
+ {
+ ULONG Source, Destination, Result;
+
+ if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Source,
&Destination))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Calculate the result */
+ Result = (Destination << Count) | (Source >> (32 - Count));
+
+ /* Update flags */
+ State->Flags.Cf = (Destination >> (32 - Count)) & 1;
+ if (Count == 1) State->Flags.Of = (Result & SIGN_FLAG_LONG)
+ != (Destination & SIGN_FLAG_LONG);
+ State->Flags.Zf = (Result == 0);
+ State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
+ State->Flags.Pf = Fast486CalculateParity(Result);
+
+ /* Write back the result */
+ return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result);
+ }
+ else
+ {
+ USHORT Source, Destination, Result;
+
+ if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Source,
&Destination))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Calculate the result */
+ Result = (Destination << Count) | (Source >> (16 - Count));
+
+ /* Update flags */
+ State->Flags.Cf = (Destination >> (16 - Count)) & 1;
+ if (Count == 1) State->Flags.Of = (Result & SIGN_FLAG_WORD)
+ != (Destination & SIGN_FLAG_WORD);
+ State->Flags.Zf = (Result == 0);
+ State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
+ State->Flags.Pf = Fast486CalculateParity(Result);
+
+ /* Write back the result */
+ return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Result);
+ }
+}
+
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushGs)
{
/* Call the internal API */
@@ -710,6 +802,98 @@
/* Return success */
return TRUE;
+}
+
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeShrd)
+{
+ BOOLEAN OperandSize, AddressSize;
+ FAST486_MOD_REG_RM ModRegRm;
+ UCHAR Count;
+
+ OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ TOGGLE_OPSIZE(OperandSize);
+ TOGGLE_ADSIZE(AddressSize);
+
+ /* Make sure this is the right instruction */
+ ASSERT((Opcode & 0xFE) == 0xAC);
+
+ /* Get the operands */
+ if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ if (Opcode == 0xAC)
+ {
+ /* Fetch the count */
+ if (!Fast486FetchByte(State, &Count))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* The count is in CL */
+ Count = State->GeneralRegs[FAST486_REG_ECX].LowByte;
+ }
+
+ /* Normalize the count */
+ if (OperandSize) Count &= 0x1F;
+ else Count &= 0x0F;
+
+ /* Do nothing if the count is zero */
+ if (Count == 0) return TRUE;
+
+ if (OperandSize)
+ {
+ ULONG Source, Destination, Result;
+
+ if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Source,
&Destination))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Calculate the result */
+ Result = (Destination >> Count) | (Source << (32 - Count));
+
+ /* Update flags */
+ State->Flags.Cf = (Destination >> (Count - 1)) & 1;
+ if (Count == 1) State->Flags.Of = (Result & SIGN_FLAG_LONG)
+ != (Destination & SIGN_FLAG_LONG);
+ State->Flags.Zf = (Result == 0);
+ State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
+ State->Flags.Pf = Fast486CalculateParity(Result);
+
+ /* Write back the result */
+ return Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result);
+ }
+ else
+ {
+ USHORT Source, Destination, Result;
+
+ if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Source,
&Destination))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Calculate the result */
+ Result = (Destination >> Count) | (Source << (16 - Count));
+
+ /* Update flags */
+ State->Flags.Cf = (Result >> (Count - 1)) & 1;
+ if (Count == 1) State->Flags.Of = (Result & SIGN_FLAG_WORD)
+ != (Destination & SIGN_FLAG_WORD);
+ State->Flags.Zf = (Result == 0);
+ State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
+ State->Flags.Pf = Fast486CalculateParity(Result);
+
+ /* Write back the result */
+ return Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Result);
+ }
}
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeImul)
Modified: branches/ntvdm/lib/fast486/extraops.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/extraops.h?re…
==============================================================================
--- branches/ntvdm/lib/fast486/extraops.h [iso-8859-1] (original)
+++ branches/ntvdm/lib/fast486/extraops.h [iso-8859-1] Mon Nov 11 00:57:59 2013
@@ -34,9 +34,11 @@
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushFs);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopFs);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBitTest);
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeShld);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePushGs);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodePopGs);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBts);
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeShrd);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeImul);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchgByte);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchg);