summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/x86new/operand.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/x86new/operand.c')
-rw-r--r--private/ntos/nthals/x86new/operand.c2026
1 files changed, 2026 insertions, 0 deletions
diff --git a/private/ntos/nthals/x86new/operand.c b/private/ntos/nthals/x86new/operand.c
new file mode 100644
index 000000000..bc2b617b5
--- /dev/null
+++ b/private/ntos/nthals/x86new/operand.c
@@ -0,0 +1,2026 @@
+/*++
+
+Copyright (c) 1994 Microsoft Corporation
+
+Module Name:
+
+ operand.c
+
+Abstract:
+
+ This module implements the operand functions necessary to decode x86
+ instruction operands.
+
+Author:
+
+ David N. Cutler (davec) 3-Sep-1994
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "nthal.h"
+#include "emulate.h"
+
+ULONG
+XmPushPopSegment (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Index;
+
+ //
+ // Push or pop segment register.
+ //
+
+ Index = P->OpcodeControl.FormatType;
+ P->DataType = WORD_DATA;
+ if (P->FunctionIndex == X86_PUSH_OP) {
+ XmSetSourceValue(P, (PVOID)(&P->SegmentRegister[Index]));
+
+ } else {
+ XmSetDestinationValue(P, (PVOID)(&P->SegmentRegister[Index]));
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmLoadSegment (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Index;
+ ULONG DataType;
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Load a segment register and a displacement value into register.
+ //
+
+ Index = P->OpcodeControl.FormatType;
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ if (P->RegisterOffsetAddress != FALSE) {
+ longjmp(&P->JumpBuffer[0], XM_ILLEGAL_REGISTER_SPECIFIER);
+ }
+
+ XmSetSourceValue(P, Operand);
+ DataType = P->DataType;
+ P->DataType = WORD_DATA;
+ Operand = XmGetOffsetAddress(P, P->Offset + DataType + 1);
+ XmSetDestinationValue(P, Operand);
+ P->SegmentRegister[Index - FormatLoadSegmentES] = P->DstValue.Word;
+ P->DataType = DataType;
+ P->DstLong = (ULONG UNALIGNED *)(&P->Gpr[Number].Exx);
+ return TRUE;
+}
+
+ULONG
+XmGroup1General (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Group 1 opcodes with general operand specifier and a direction
+ // bit.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ if ((P->CurrentOpcode & DIRECTION_BIT) == 0) {
+ XmSetDestinationValue(P, Operand);
+ XmSetSourceValue(P, XmGetRegisterAddress(P, Number));
+
+ } else {
+ XmSetDestinationValue(P, XmGetRegisterAddress(P, Number));
+ XmSetSourceValue(P, Operand);
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmGroup1Immediate (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+ ULONG Source;
+
+ //
+ // Group 1 opcode with general operand specifier and an immediate
+ // operand.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ Source = XmGetImmediateSourceValue(P, P->CurrentOpcode & SIGN_BIT);
+ XmSetDestinationValue(P, Operand);
+ XmSetImmediateSourceValue(P, Source);
+ P->FunctionIndex += Number;
+ return TRUE;
+}
+
+ULONG
+XmGroup2By1 (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+ ULONG Source;
+
+ //
+ // Group 2 shift opcodes with a general operand specifier and a
+ // shift count of 1.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ Source = 1;
+ XmSetImmediateSourceValue(P, Source);
+ XmSetDestinationValue(P, Operand);
+ P->FunctionIndex += Number;
+ return TRUE;
+}
+
+ULONG
+XmGroup2ByCL (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+ ULONG Source;
+
+ //
+ // Group 2 shift opcodes with a general operand specifier and a
+ // CL shift count.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ Source = (ULONG)P->Gpr[CL].Xl & 0x1f;
+ XmSetImmediateSourceValue(P, Source);
+ XmSetDestinationValue(P, Operand);
+ P->FunctionIndex += Number;
+ return TRUE;
+}
+
+ULONG
+XmGroup2ByByte (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+ ULONG Source;
+
+ //
+ // Group 2 shift opcodes with a general operand specifier and a
+ // byte immediate shift count.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ Source = XmGetByteImmediate(P) & 0x1f;
+ XmSetImmediateSourceValue(P, Source);
+ XmSetDestinationValue(P, Operand);
+ P->FunctionIndex += Number;
+ return TRUE;
+}
+
+ULONG
+XmGroup3General (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+ ULONG Source;
+
+ //
+ // Group 3 opcodes with general operand specifier.
+ //
+ // N.B. The test operator for this group has an immediate operand
+ // and the multiply and divide operators use the accumulator
+ // as a source. The not and neg operators are unary.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ P->FunctionIndex += Number;
+ if (P->FunctionIndex == X86_TEST_OP) {
+ Source = XmGetImmediateSourceValue(P, 0);
+ XmSetDestinationValue(P, Operand);
+ XmSetImmediateSourceValue(P, Source);
+
+ } else {
+
+ //
+ // If the operation is a mulitply or divide, then there is an
+ // implied operand which is AL, AX, or EAX. If the operation is
+ // a divide, then there is an additional implied operand which
+ // is AH, DX, or EDX.
+ //
+
+ if ((Number & 0x4) != 0) {
+ if ((Number & 0x2) == 0) {
+ XmSetDestinationValue(P, (PVOID)(&P->Gpr[EAX].Exx));
+
+ } else {
+ P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[EAX].Exx);
+ }
+
+ XmSetSourceValue(P, Operand);
+
+ } else {
+ XmSetDestinationValue(P, Operand);
+ }
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmGroup45General (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG DataType;
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Group 4 and group 5 unary opcodes with general operand specifier.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ if (P->OpcodeControl.FormatType == FormatGroup4General) {
+ Number &= 0x1;
+ }
+
+ P->FunctionIndex += Number;
+ if (P->FunctionIndex == X86_PUSH_OP) {
+ XmSetSourceValue(P, Operand);
+
+ } else {
+
+ //
+ // If the operation is a call or jump that specifies a segment,
+ // then get the segment value.
+ //
+
+ XmSetDestinationValue(P, Operand);
+ if ((Number == 3) || (Number == 5)) {
+ if (P->RegisterOffsetAddress != FALSE) {
+ longjmp(&P->JumpBuffer[0], XM_ILLEGAL_REGISTER_SPECIFIER);
+ }
+
+ DataType = P->DataType;
+ P->DataType = WORD_DATA;
+ Operand = XmGetOffsetAddress(P, P->Offset + DataType + 1);
+ XmSetSourceValue(P, Operand);
+ P->DstSegment = P->SrcValue.Word;
+ P->DataType = DataType;
+ }
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmGroup8BitOffset (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Offset;
+ ULONG Number;
+
+ //
+ // Bit test opcodes with an immediate bit offset and a memory or
+ // register operand.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ Offset = XmGetByteImmediate(P);
+ XmSetImmediateSourceValue(P, Offset);
+ if (P->RegisterOffsetAddress == FALSE) {
+ if (P->DataType == LONG_DATA) {
+ Offset = (P->SrcValue.Long >> 5) << 2;
+
+ } else {
+ Offset = (P->SrcValue.Long >> 4) << 1;
+ }
+
+ Operand = XmGetOffsetAddress(P, Offset + P->Offset);
+ }
+
+ if (P->DataType == LONG_DATA) {
+ P->SrcValue.Long &= 0x1f;
+
+ } else {
+ P->SrcValue.Long &= 0xf;
+ }
+
+ XmSetDestinationValue(P, Operand);
+ P->FunctionIndex += (Number & 0x3);
+ return TRUE;
+}
+
+ULONG
+XmOpcodeRegister (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Number;
+
+ //
+ // Unary opodes with a general register encoded in the low
+ // 3 bits of the opcode value.
+ //
+
+ Number = P->CurrentOpcode & 0x7;
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ if (P->FunctionIndex == X86_PUSH_OP) {
+ XmSetSourceValue(P, (PVOID)(&P->Gpr[Number].Exx));
+
+ } else {
+ XmSetDestinationValue(P, (PVOID)(&P->Gpr[Number].Exx));
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmLongJump (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Offset;
+
+ //
+ // Long jump with opcode containing the control for conditional
+ // jumps. The destination of the jump is stored in the destination
+ // value and the jump control is stored in the sources value.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ Offset = XmGetLongImmediate(P);
+ P->DstValue.Long = P->Eip + Offset;
+
+ } else {
+ Offset = XmGetWordImmediate(P);
+ P->DstValue.Long = (USHORT)(Offset + P->Eip);
+ }
+
+ P->SrcValue.Long = P->CurrentOpcode & 0xf;
+ return TRUE;
+}
+
+ULONG
+XmShortJump (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Offset;
+
+ //
+ // Short jump with opcode containing the control for conditional
+ // jumps. The destination of the jump is stored in the destination
+ // value and the jump control is stored in the sources value.
+ //
+
+ Offset = (ULONG)XmGetSignedByteImmediateToWord(P);
+ P->DstValue.Long = (USHORT)(Offset + P->Eip);
+ P->SrcValue.Long = P->CurrentOpcode & 0xf;
+ return TRUE;
+}
+
+ULONG
+XmSetccByte (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Number;
+
+ //
+ // General byte destination with reg field ignored and the opcode
+ // containing the condition control.
+ //
+
+ P->DataType = BYTE_DATA;
+ P->DstByte = (UCHAR UNALIGNED *)XmEvaluateAddressSpecifier(P, &Number);
+ P->SrcValue.Long = P->CurrentOpcode & 0xf;
+ return TRUE;
+}
+
+ULONG
+XmAccumImmediate (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Source;
+
+ //
+ // Accumulator destination and immediate source operands.
+ //
+
+ XmSetDataType(P);
+ Source = XmGetImmediateSourceValue(P, 0);
+ XmSetDestinationValue(P, (PVOID)(&P->Gpr[EAX].Exx));
+ XmSetImmediateSourceValue(P, Source);
+ return TRUE;
+}
+
+ULONG
+XmAccumRegister (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Number;
+
+ //
+ // Accumulator destination and a general register source encoded in
+ // the low 3-bits of the opcode value.
+ //
+
+ Number = P->CurrentOpcode & 0x7;
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ XmSetSourceValue(P, (PVOID)(&P->Gpr[Number].Exx));
+ XmSetDestinationValue(P, (PVOID)(&P->Gpr[EAX].Exx));
+ return TRUE;
+}
+
+ULONG
+XmMoveGeneral (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Move opcodes with general operand specifier and a direction bit.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ if ((P->CurrentOpcode & DIRECTION_BIT) == 0) {
+ P->DstLong = (ULONG UNALIGNED *)Operand;
+ XmSetSourceValue(P, XmGetRegisterAddress(P, Number));
+
+ } else {
+ P->DstLong = (ULONG UNALIGNED *)XmGetRegisterAddress(P, Number);
+ XmSetSourceValue(P, Operand);
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmMoveImmediate (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+ ULONG Source;
+
+ //
+ // Move opcodes with general operand specifier and an immediate
+ // operand.
+ //
+
+ XmSetDataType(P);
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ P->DstLong = (ULONG UNALIGNED *)Operand;
+ Source = XmGetImmediateSourceValue(P, 0);
+ XmSetImmediateSourceValue(P, Source);
+ return TRUE;
+}
+
+ULONG
+XmMoveRegImmediate (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Number;
+
+ //
+ // Move register immediate opcodes with a general register encoded
+ // in the low 3-bits of the opcode value and an immediate operand.
+ //
+
+ Number = P->CurrentOpcode & 0x7;
+ if ((P->CurrentOpcode & 0x8) == 0) {
+ P->DataType = BYTE_DATA;
+
+ } else {
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+ }
+
+ P->DstLong = (ULONG UNALIGNED *)XmGetRegisterAddress(P, Number);
+ XmSetImmediateSourceValue(P, XmGetImmediateSourceValue(P, 0));
+ return TRUE;
+}
+
+ULONG
+XmSegmentOffset (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Offset;
+
+ //
+ // Move opcodes with an implied accumlator operand and an immediate
+ // segment offset and a direction bit.
+ //
+
+ XmSetDataType(P);
+ if (P->OpaddrPrefixActive != FALSE) {
+ Offset = XmGetLongImmediate(P);
+
+ } else {
+ Offset = XmGetWordImmediate(P);
+ }
+
+ Operand = XmGetOffsetAddress(P, Offset);
+ if ((P->CurrentOpcode & DIRECTION_BIT) == 0) {
+ P->DstLong = (ULONG UNALIGNED *)(&P->Gpr[EAX].Exx);
+ XmSetSourceValue(P, Operand);
+
+ } else {
+ P->DstLong = (ULONG UNALIGNED *)Operand;
+ XmSetSourceValue(P, &P->Gpr[EAX].Exx);
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmMoveSegment (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Move segment opcodes with general operand specifier and a direction
+ // bit.
+ //
+
+ P->DataType = WORD_DATA;
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ if ((P->CurrentOpcode & DIRECTION_BIT) == 0) {
+ P->DstLong = (ULONG UNALIGNED *)Operand;
+ XmSetSourceValue(P, (PVOID)(&P->SegmentRegister[Number]));
+
+ } else {
+ P->DstLong = (ULONG UNALIGNED *)(&P->SegmentRegister[Number]);
+ XmSetSourceValue(P, Operand);
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmMoveXxGeneral (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Move zero or sign extended opcodes with general operand specifier.
+ //
+
+ if ((P->CurrentOpcode & WIDTH_BIT) == 0) {
+ P->DataType = BYTE_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ XmSetSourceValue(P, Operand);
+ if (P->DataType == BYTE_DATA) {
+ if ((P->CurrentOpcode & 0x8) == 0) {
+ P->SrcValue.Long = (ULONG)P->SrcValue.Byte;
+
+ } else {
+ P->SrcValue.Long = (ULONG)((LONG)((SCHAR)P->SrcValue.Byte));
+ }
+
+ } else {
+ if ((P->CurrentOpcode & 0x8) == 0) {
+ P->SrcValue.Long = (ULONG)P->SrcValue.Word;
+
+ } else {
+ P->SrcValue.Long = (ULONG)((LONG)((SHORT)P->SrcValue.Word));
+ }
+ }
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ P->SrcValue.Long &= 0xffff;
+ }
+
+ P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[Number].Exx);
+ return TRUE;
+}
+
+ULONG
+XmFlagsRegister (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ //
+ // Flags register source or destination with a stack source or
+ // destination.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ if (P->FunctionIndex == X86_PUSH_OP) {
+ XmSetSourceValue(P, (PVOID)(&P->AllFlags));
+
+ } else {
+ XmSetDestinationValue(P, (PVOID)(&P->AllFlags));
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmPushImmediate (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Source;
+
+ //
+ // Push opcode with an immediate operand.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Source = XmGetImmediateSourceValue(P, P->CurrentOpcode & SIGN_BIT);
+ XmSetImmediateSourceValue(P, Source);
+ return TRUE;
+}
+
+ULONG
+XmPopGeneral (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Pop opcode with a general specifier.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ XmSetDestinationValue(P, Operand);
+ return TRUE;
+}
+
+ULONG
+XmImulImmediate (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Number;
+ PVOID Operand;
+ ULONG Source;
+
+ //
+ // Multiply signed opcode with a general specifier and an immediate
+ // operand.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ Source = XmGetImmediateSourceValue(P, P->CurrentOpcode & SIGN_BIT);
+ XmSetImmediateSourceValue(P, Source);
+ XmSetDestinationValue(P, Operand);
+ P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[Number].Exx);
+ return TRUE;
+}
+
+ULONG
+XmStringOperands (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ //
+ // String opcode with implicit operands of eSI and eDI.
+ //
+
+ XmSetDataType(P);
+ return TRUE;
+}
+
+ULONG
+XmEffectiveOffset (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Effective offset opcodes with general operand specifier.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ P->ComputeOffsetAddress = TRUE;
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ if (P->RegisterOffsetAddress != FALSE) {
+ longjmp(&P->JumpBuffer[0], XM_ILLEGAL_REGISTER_SPECIFIER);
+ }
+
+ P->SrcValue.Long = (ULONG)Operand;
+ XmTraceSource(P, P->SrcValue.Long);
+ P->DstLong = (ULONG UNALIGNED *)(&P->Gpr[Number].Exx);
+ return TRUE;
+}
+
+ULONG
+XmImmediateJump (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ //
+ // Immediate long jump with the destination offset and new CS
+ // segment value. The destination of the jump is stored in the
+ // destination value and the new CS segment value is stored in
+ // destination segment.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DstValue.Long = XmGetLongImmediate(P);
+
+ } else {
+ P->DstValue.Long = XmGetWordImmediate(P);
+ }
+
+ P->DstSegment = XmGetWordImmediate(P);
+ return TRUE;
+}
+
+ULONG
+XmImmediateEnter (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ enter
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ //
+ // Enter operands with an allocation size and level number.
+ //
+
+ P->SrcValue.Long = XmGetWordImmediate(P);
+ P->DstValue.Long = XmGetByteImmediate(P) & 0x1f;
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ return TRUE;
+}
+
+ULONG
+XmGeneralBitOffset (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Offset;
+ ULONG Number;
+
+ //
+ // Bit test opcodes with a register bit offset and a memory or
+ // register operand.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ XmSetSourceValue(P, (PVOID)(&P->Gpr[Number].Exx));
+ if (P->RegisterOffsetAddress == FALSE) {
+ if (P->DataType == LONG_DATA) {
+ Offset = (P->SrcValue.Long >> 5) << 2;
+
+ } else {
+ Offset = (P->SrcValue.Long >> 4) << 1;
+ }
+
+ Operand = XmGetOffsetAddress(P, Offset + P->Offset);
+ }
+
+ if (P->DataType == LONG_DATA) {
+ P->SrcValue.Long &= 0x1f;
+
+ } else {
+ P->SrcValue.Long &= 0xf;
+ }
+
+ XmSetDestinationValue(P, Operand);
+ return TRUE;
+}
+
+ULONG
+XmShiftDouble (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ shld shrd
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+ ULONG Source;
+
+ //
+ // Shift double operators with an immediate byte or cl shift count.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ if ((P->CurrentOpcode & 0x1) == 0) {
+ Source = XmGetByteImmediate(P);
+
+ } else {
+ Source = P->Gpr[CX].Xl;
+ }
+
+ if (P->DataType == LONG_DATA) {
+ P->Shift = (UCHAR)(Source & 0x1f);
+
+ } else {
+ P->Shift = (UCHAR)(Source & 0xf);
+ }
+
+ XmSetSourceValue(P, (PVOID)(&P->Gpr[Number].Exx));
+ XmSetDestinationValue(P, Operand);
+ return TRUE;
+}
+
+ULONG
+XmPortImmediate (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Source;
+
+ //
+ // In/out opcodes with an immediate port and all other operands implied.
+ //
+
+ Source = (ULONG)XmGetByteImmediate(P);
+ P->DataType = WORD_DATA;
+ XmSetImmediateSourceValue(P, Source);
+ XmSetDataType(P);
+ return TRUE;
+}
+
+ULONG
+XmPortDX (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Source;
+
+ //
+ // In/out opcodes with a port in DX with all other operands implied.
+ //
+
+ Source = P->Gpr[DX].Xx;
+ P->DataType = WORD_DATA;
+ XmSetImmediateSourceValue(P, Source);
+ XmSetDataType(P);
+ return TRUE;
+}
+
+ULONG
+XmBitScanGeneral (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // Bit scan general opcodes with general operand specifier.
+ // bit.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ P->DstLong = (ULONG UNALIGNED *)(&P->Gpr[Number].Exx);
+ XmSetSourceValue(P, Operand);
+ return TRUE;
+}
+
+ULONG
+XmByteImmediate (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ int xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ ULONG Source;
+
+ //
+ // int opcode with an immediate operand.
+ //
+
+ P->DataType = BYTE_DATA;
+ Source = XmGetImmediateSourceValue(P, 0);
+ XmSetImmediateSourceValue(P, Source);
+ return TRUE;
+}
+
+ULONG
+XmXlatOpcode (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xlat
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Offset;
+
+ //
+ // xlat opcode with zero extended [AL] + [eBX] as the effective
+ // address.
+ //
+
+ P->DataType = BYTE_DATA;
+ if (P->OpaddrPrefixActive != FALSE) {
+ Offset = P->Gpr[EBX].Exx + P->Gpr[AL].Xl;
+
+ } else {
+ Offset = P->Gpr[BX].Xx + P->Gpr[AL].Xl;
+ }
+
+ Operand = XmGetOffsetAddress(P, Offset);
+ XmSetSourceValue(P, Operand);
+ P->DstByte = (UCHAR UNALIGNED *)(&P->Gpr[AL].Xl);
+ return TRUE;
+}
+
+ULONG
+XmGeneralRegister (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ bswap
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ PVOID Operand;
+ ULONG Number;
+
+ //
+ // General register source and destination.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ }
+
+ Operand = XmEvaluateAddressSpecifier(P, &Number);
+ if (P->RegisterOffsetAddress == FALSE) {
+ longjmp(&P->JumpBuffer[0], XM_ILLEGAL_GENERAL_SPECIFIER);
+ }
+
+ XmSetSourceValue(P, (PVOID)(&P->Gpr[Number].Exx));
+ P->DstLong = (ULONG UNALIGNED *)(&P->Gpr[Number].Exx);
+ return TRUE;
+}
+
+ULONG
+XmOpcodeEscape (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ 2-byte escape
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of xx is returned as the function value.
+
+--*/
+
+{
+
+ //
+ // Two byte opcode escape.
+ //
+
+ P->OpcodeControlTable = &XmOpcodeControlTable2[0];
+
+#if defined(XM_DEBUG)
+
+ P->OpcodeNameTable = &XmOpcodeNameTable2[0];
+
+#endif
+
+ return FALSE;
+}
+
+ULONG
+XmPrefixOpcode (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ CS: DS; ES: SS: FS: GS: lock adrsize
+ opsize repz repnz
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of FALSE is returned as the function value.
+
+--*/
+
+{
+
+ //
+ // Case on the function index.
+ //
+
+ switch (P->FunctionIndex) {
+
+ //
+ // Segment override prefix.
+ //
+ // Set the segment override prefix flags and the data segment
+ // number.
+ //
+
+ case X86_ES_OP:
+ case X86_CS_OP:
+ case X86_SS_OP:
+ case X86_DS_OP:
+ case X86_FS_OP:
+ case X86_GS_OP:
+ P->SegmentPrefixActive = TRUE;
+ P->DataSegment = P->FunctionIndex;
+ XmTraceOverride(P);
+ break;
+
+ //
+ // Lock prefix.
+ //
+ // Set the lock prefix flags.
+ //
+
+ case X86_LOCK_OP:
+ P->LockPrefixActive = TRUE;
+ break;
+
+ //
+ // Address size prefix.
+ //
+ // Set the address size prefix flag.
+ //
+
+ case X86_ADSZ_OP:
+ P->OpaddrPrefixActive = TRUE;
+ break;
+
+ //
+ // Operand size prefix.
+ //
+ // Set the operand size prefix flag.
+ //
+
+
+ case X86_OPSZ_OP:
+ P->OpsizePrefixActive = TRUE;
+ break;
+
+ //
+ // Repeat until ECX or ZF equals zero
+ //
+ // Set up repeat until ECX or ZF equals zero prefix flags.
+ //
+
+ case X86_REPZ_OP:
+ P->RepeatPrefixActive = TRUE;
+ P->RepeatZflag = 1;
+ break;
+
+ //
+ // Repeat until ECX equals zero or ZF equals one.
+ //
+ // Set up repeat until ECX equals zero or ZF equals one prefix
+ // flags.
+ //
+
+ case X86_REPNZ_OP:
+ P->RepeatPrefixActive = TRUE;
+ P->RepeatZflag = 0;
+ break;
+ }
+
+ return FALSE;
+}
+
+ULONG
+XmNoOperands (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function decodes x86 operand specifiers for the following opcodes:
+
+ xxxxxx
+
+Arguments:
+
+ P - Supplies a pointer to an emulator context structure.
+
+Return Value:
+
+ A completion status of TRUE is returned as the function value.
+
+--*/
+
+{
+
+ return TRUE;
+}