summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/x86new/mulops.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/nthals/x86new/mulops.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/nthals/x86new/mulops.c')
-rw-r--r--private/ntos/nthals/x86new/mulops.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/private/ntos/nthals/x86new/mulops.c b/private/ntos/nthals/x86new/mulops.c
new file mode 100644
index 000000000..cc020d392
--- /dev/null
+++ b/private/ntos/nthals/x86new/mulops.c
@@ -0,0 +1,202 @@
+/*++
+
+Copyright (c) 1994 Microsoft Corporation
+
+Module Name:
+
+ mulops.c
+
+Abstract:
+
+ This module implements the code to emulate the mul and imul opcodes.
+
+Author:
+
+ David N. Cutler (davec) 21-Sep-1994
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "nthal.h"
+#include "emulate.h"
+
+VOID
+XmImulOp (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function emulates an imul opcode with a single destination.
+
+Arguments:
+
+ P - Supplies a pointer to the emulation context structure.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ LARGE_INTEGER Product;
+ ULONG UpperEqual;
+
+ //
+ // Multiply the signed operands and store result.
+ //
+
+ if (P->DataType == BYTE_DATA) {
+ Product.QuadPart = Int32x32To64((LONG)((SCHAR)P->DstValue.Byte),
+ (LONG)((SCHAR)P->SrcValue.Byte));
+
+ XmStoreResult(P, Product.LowPart & 0xff);
+ UpperEqual = ((UCHAR)((Product.LowPart >> 8) & 0xff) !=
+ (UCHAR)((SCHAR)Product.LowPart >> 7));
+
+ } else if (P->DataType == LONG_DATA) {
+ Product.QuadPart = Int32x32To64((LONG)P->DstValue.Long,
+ (LONG)P->SrcValue.Long);
+
+ XmStoreResult(P, Product.LowPart);
+ UpperEqual = (Product.HighPart != (LONG)Product.LowPart >> 31);
+
+ } else {
+ Product.QuadPart = Int32x32To64((LONG)((SHORT)P->DstValue.Word),
+ (LONG)((SHORT)P->SrcValue.Word));
+
+ XmStoreResult(P, Product.LowPart & 0xffff);
+ UpperEqual = ((USHORT)((Product.LowPart >> 16) & 0xffff) !=
+ (USHORT)((SHORT)Product.LowPart >> 15));
+ }
+
+ P->Eflags.CF = UpperEqual;
+ P->Eflags.OF = UpperEqual;
+ return;
+}
+
+VOID
+XmImulxOp (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function emulates an imul opcode with an extended destination.
+
+Arguments:
+
+ P - Supplies a pointer to the emulation context structure.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ LARGE_INTEGER Product;
+ ULONG UpperEqual;
+
+ //
+ // Multiply the signed operands and store the result and the extended
+ // result.
+ //
+
+ if (P->DataType == BYTE_DATA) {
+ Product.QuadPart = Int32x32To64((LONG)((SCHAR)P->DstValue.Byte),
+ (LONG)((SCHAR)P->SrcValue.Byte));
+
+ P->DataType = WORD_DATA;
+ XmStoreResult(P, Product.LowPart & 0xffff);
+ UpperEqual = (P->Gpr[AX].Xh != (UCHAR)((SCHAR)P->Gpr[AX].Xl >> 7));
+
+ } else if (P->DataType == LONG_DATA) {
+ Product.QuadPart = Int32x32To64((LONG)P->DstValue.Long,
+ (LONG)P->SrcValue.Long);
+
+ XmStoreResult(P, Product.LowPart);
+ P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[EDX].Exx);
+ XmStoreResult(P, (ULONG)Product.HighPart);
+ UpperEqual = (Product.HighPart != (LONG)Product.LowPart >> 31);
+
+ } else {
+ Product.QuadPart = Int32x32To64((LONG)((SHORT)P->DstValue.Word),
+ (LONG)((SHORT)P->SrcValue.Word));
+
+ XmStoreResult(P, Product.LowPart & 0xffff);
+ P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[DX].Exx);
+ XmStoreResult(P, Product.LowPart >> 16);
+ UpperEqual = (P->Gpr[DX].Xx != (USHORT)((SHORT)P->Gpr[AX].Xx >> 15));
+ }
+
+ P->Eflags.CF = UpperEqual;
+ P->Eflags.OF = UpperEqual;
+ return;
+}
+
+VOID
+XmMulOp (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function emulates a mul opcode.
+
+Arguments:
+
+ P - Supplies a pointer to the emulation context structure.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULARGE_INTEGER Product;
+ ULONG UpperZero;
+
+ //
+ // Multiply the unsigned operands and store result.
+ //
+
+ Product.QuadPart = UInt32x32To64(P->DstValue.Long, P->SrcValue.Long);
+ if (P->DataType == BYTE_DATA) {
+ P->DataType = WORD_DATA;
+ XmStoreResult(P, Product.LowPart);
+ UpperZero = (P->Gpr[AX].Xh != 0);
+
+ } else if (P->DataType == LONG_DATA) {
+ XmStoreResult(P, Product.LowPart);
+ P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[EDX].Exx);
+ XmStoreResult(P, Product.HighPart);
+ UpperZero = (Product.HighPart != 0);
+
+ } else {
+ XmStoreResult(P, Product.LowPart & 0xffff);
+ P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[DX].Exx);
+ XmStoreResult(P, Product.LowPart >> 16);
+ UpperZero = (P->Gpr[DX].Xx != 0);
+ }
+
+ P->Eflags.CF = UpperZero;
+ P->Eflags.OF = UpperZero;
+ return;
+}