summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/x86new/setops.c
blob: e584921903551b3ce5c5336539423d9e01344df9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*++

Copyright (c) 1994  Microsoft Corporation

Module Name:

    setops.c

Abstract:

    This module implements the code to emulate set opcodes.

Author:

    David N. Cutler (davec) 13-Sep-1994

Environment:

    Kernel mode only.

Revision History:

--*/

#include "nthal.h"
#include "emulate.h"

VOID
XmSxxOp (
    IN PRXM_CONTEXT P
    )

/*++

Routine Description:

    This function emulates set byte on condition opcodes.

Arguments:

    P - Supplies a pointer to the emulation context structure.

Return Value:

    None.

--*/

{

    ULONG Complement;
    ULONG Condition;

    //
    // Case on the set control value.
    //

    Complement = P->SrcValue.Long & 1;
    switch (P->SrcValue.Long >> 1) {

        //
        // Set if overflow/not overflow.
        //

    case 0:
        Condition = P->Eflags.OF;
        break;

        //
        // Set if below/not below.
        //

    case 1:
        Condition = P->Eflags.CF;
        break;

        //
        // Set if zero/not zero.
        //

    case 2:
        Condition = P->Eflags.ZF;
        break;

        //
        // Set if below or equal/not below or equal.
        //

    case 3:
        Condition = P->Eflags.CF | P->Eflags.ZF;
        break;

        //
        // Set if signed/not signed.
        //

    case 4:
        Condition = P->Eflags.SF;
        break;

        //
        // Set if parity/not parity.
        //

    case 5:
        Condition = P->Eflags.PF;
        break;

        //
        // Set if less/not less.
        //

    case 6:
        Condition = (P->Eflags.SF ^ P->Eflags.OF);
        break;

        //
        // Set 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 byte destination
    // value to one. Otherwise, set the byte destination value to zero.
    //

    XmStoreResult(P, (ULONG)(Condition ^ Complement));
    return;
}