diff options
Diffstat (limited to 'private/ntos/nthals/x86new/jmpops.c')
-rw-r--r-- | private/ntos/nthals/x86new/jmpops.c | 290 |
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; +} |