summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/x86new/jmpops.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/x86new/jmpops.c')
-rw-r--r--private/ntos/nthals/x86new/jmpops.c290
1 files changed, 290 insertions, 0 deletions
diff --git a/private/ntos/nthals/x86new/jmpops.c b/private/ntos/nthals/x86new/jmpops.c
new file mode 100644
index 000000000..abb261865
--- /dev/null
+++ b/private/ntos/nthals/x86new/jmpops.c
@@ -0,0 +1,290 @@
+/*++
+
+Copyright (c) 1994 Microsoft Corporation
+
+Module Name:
+
+ jmpops.c
+
+Abstract:
+
+ This module implements the code to emulate jump opcodes.
+
+Author:
+
+ David N. Cutler (davec) 13-Sep-1994
+
+Environment:
+
+ Kernel mode only.
+
+Revision History:
+
+--*/
+
+#include "nthal.h"
+#include "emulate.h"
+
+VOID
+XmJcxzOp (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function emulates a jcxz instruction.
+
+Arguments:
+
+ P - Supplies a pointer to the emulation context structure.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG Condition;
+
+ //
+ // If eCX is zero, then set the new IP value.
+ //
+
+ if (P->OpsizePrefixActive != FALSE) {
+ Condition = P->Gpr[ECX].Exx;
+
+ } else {
+ Condition = P->Gpr[CX].Xx;
+ }
+
+ if (Condition == 0) {
+ P->Eip = P->DstValue.Word;
+ XmTraceJumps(P);
+ }
+
+ return;
+}
+
+VOID
+XmJmpOp (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function emulates a jmp near relative instruction.
+
+Arguments:
+
+ P - Supplies a pointer to the emulation context structure.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Set the destination segment, if required, and set the new IP.
+ //
+
+ P->Eip = P->DstValue.Long;
+ if ((P->CurrentOpcode == 0xea) || (P->FunctionIndex != X86_JMP_OP)) {
+ P->SegmentRegister[CS] = P->DstSegment;
+ }
+
+ XmTraceJumps(P);
+ return;
+}
+
+VOID
+XmJxxOp (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function emulates conditional jump instructions.
+
+Arguments:
+
+ P - Supplies a pointer to the emulation context structure.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG Complement;
+ ULONG Condition;
+
+ //
+ // Case on the jump control value.
+ //
+
+ Complement = P->SrcValue.Long & 1;
+ switch (P->SrcValue.Long >> 1) {
+
+ //
+ // Jump if overflow/not overflow.
+ //
+
+ case 0:
+ Condition = P->Eflags.OF;
+ break;
+
+ //
+ // Jump if below/not below.
+ //
+
+ case 1:
+ Condition = P->Eflags.CF;
+ break;
+
+ //
+ // Jump if zero/not zero.
+ //
+
+ case 2:
+ Condition = P->Eflags.ZF;
+ break;
+
+ //
+ // Jump if below or equal/not below or equal.
+ //
+
+ case 3:
+ Condition = P->Eflags.CF | P->Eflags.ZF;
+ break;
+
+ //
+ // Jump if signed/not signed.
+ //
+
+ case 4:
+ Condition = P->Eflags.SF;
+ break;
+
+ //
+ // Jump if parity/not parity.
+ //
+
+ case 5:
+ Condition = P->Eflags.PF;
+ break;
+
+ //
+ // Jump if less/not less.
+ //
+
+ case 6:
+ Condition = (P->Eflags.SF ^ P->Eflags.OF);
+ break;
+
+ //
+ // Jump if less or equal/not less or equal.
+ //
+
+ case 7:
+ Condition = (P->Eflags.SF ^ P->Eflags.OF) | P->Eflags.ZF;
+ break;
+ }
+
+ //
+ // If the specified condition is met, then set the new IP value.
+ //
+
+ if ((Condition ^ Complement) != 0) {
+ P->Eip = P->DstValue.Word;
+ XmTraceJumps(P);
+ }
+
+ return;
+}
+
+VOID
+XmLoopOp (
+ IN PRXM_CONTEXT P
+ )
+
+/*++
+
+Routine Description:
+
+ This function emulates loop, loopz, or a loopnz instructions.
+
+Arguments:
+
+ P - Supplies a pointer to the emulation context structure.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ ULONG Condition;
+ ULONG Result;
+ ULONG Type;
+
+ //
+ // Set the address of the destination and compute the result value.
+ //
+
+ Result = P->Gpr[ECX].Exx - 1;
+ P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[ECX].Exx);
+ if (P->OpaddrPrefixActive != FALSE) {
+ P->DataType = LONG_DATA;
+
+ } else {
+ P->DataType = WORD_DATA;
+ Result &= 0xffff;
+ }
+
+ XmStoreResult(P, Result);
+
+ //
+ // Isolate the loop type and test the appropriate condition.
+ //
+ // Type 0 - loopnz
+ // 1 - loopz
+ // 2 - loop
+ //
+
+ Type = P->CurrentOpcode & 3;
+ if (Type == 0) {
+ Condition = P->Eflags.ZF ^ 1;
+
+ } else if (Type == 1) {
+ Condition = P->Eflags.ZF;
+
+ } else {
+ Condition = TRUE;
+ }
+
+ //
+ // If the loop condition is met, then set the new IP value.
+ //
+
+ if ((Condition != FALSE) && (Result != 0)) {
+ P->Eip = P->DstValue.Word;
+ XmTraceJumps(P);
+ }
+
+ return;
+}