|
60 | 60 |
|
61 | 61 | static const struct instr_emul_vie_op two_byte_opcodes[256] = {
|
62 | 62 | [0xB6] = {
|
63 |
| - .op_byte = 0xB6, |
64 | 63 | .op_type = VIE_OP_TYPE_MOVZX,
|
65 | 64 | },
|
66 | 65 | [0xB7] = {
|
67 |
| - .op_byte = 0xB7, |
68 | 66 | .op_type = VIE_OP_TYPE_MOVZX,
|
69 | 67 | },
|
70 | 68 | [0xBA] = {
|
71 |
| - .op_byte = 0xBA, |
72 | 69 | .op_type = VIE_OP_TYPE_BITTEST,
|
73 | 70 | .op_flags = VIE_OP_F_IMM8,
|
74 | 71 | },
|
75 | 72 | [0xBE] = {
|
76 |
| - .op_byte = 0xBE, |
77 | 73 | .op_type = VIE_OP_TYPE_MOVSX,
|
78 | 74 | },
|
79 | 75 | };
|
80 | 76 |
|
81 | 77 | static const struct instr_emul_vie_op one_byte_opcodes[256] = {
|
82 | 78 | [0x0F] = {
|
83 |
| - .op_byte = 0x0FU, |
84 | 79 | .op_type = VIE_OP_TYPE_TWO_BYTE
|
85 | 80 | },
|
86 | 81 | [0x2B] = {
|
87 |
| - .op_byte = 0x2BU, |
88 | 82 | .op_type = VIE_OP_TYPE_SUB,
|
89 | 83 | },
|
90 | 84 | [0x39] = {
|
91 |
| - .op_byte = 0x39U, |
92 | 85 | .op_type = VIE_OP_TYPE_CMP,
|
93 | 86 | },
|
94 | 87 | [0x3B] = {
|
95 |
| - .op_byte = 0x3BU, |
96 | 88 | .op_type = VIE_OP_TYPE_CMP,
|
97 | 89 | },
|
98 | 90 | [0x88] = {
|
99 |
| - .op_byte = 0x88U, |
100 | 91 | .op_type = VIE_OP_TYPE_MOV,
|
101 | 92 | },
|
102 | 93 | [0x89] = {
|
103 |
| - .op_byte = 0x89U, |
104 | 94 | .op_type = VIE_OP_TYPE_MOV,
|
105 | 95 | },
|
106 | 96 | [0x8A] = {
|
107 |
| - .op_byte = 0x8AU, |
108 | 97 | .op_type = VIE_OP_TYPE_MOV,
|
109 | 98 | },
|
110 | 99 | [0x8B] = {
|
111 |
| - .op_byte = 0x8BU, |
112 | 100 | .op_type = VIE_OP_TYPE_MOV,
|
113 | 101 | },
|
114 | 102 | [0xA1] = {
|
115 |
| - .op_byte = 0xA1U, |
116 | 103 | .op_type = VIE_OP_TYPE_MOV,
|
117 | 104 | .op_flags = VIE_OP_F_MOFFSET | VIE_OP_F_NO_MODRM,
|
118 | 105 | },
|
119 | 106 | [0xA3] = {
|
120 |
| - .op_byte = 0xA3U, |
121 | 107 | .op_type = VIE_OP_TYPE_MOV,
|
122 | 108 | .op_flags = VIE_OP_F_MOFFSET | VIE_OP_F_NO_MODRM,
|
123 | 109 | },
|
124 | 110 | [0xA4] = {
|
125 |
| - .op_byte = 0xA4U, |
126 | 111 | .op_type = VIE_OP_TYPE_MOVS,
|
127 | 112 | .op_flags = VIE_OP_F_NO_MODRM | VIE_OP_F_NO_GLA_VERIFICATION
|
128 | 113 | },
|
129 | 114 | [0xA5] = {
|
130 |
| - .op_byte = 0xA5U, |
131 | 115 | .op_type = VIE_OP_TYPE_MOVS,
|
132 | 116 | .op_flags = VIE_OP_F_NO_MODRM | VIE_OP_F_NO_GLA_VERIFICATION
|
133 | 117 | },
|
134 | 118 | [0xAA] = {
|
135 |
| - .op_byte = 0xAAU, |
136 | 119 | .op_type = VIE_OP_TYPE_STOS,
|
137 | 120 | .op_flags = VIE_OP_F_NO_MODRM | VIE_OP_F_NO_GLA_VERIFICATION
|
138 | 121 | },
|
139 | 122 | [0xAB] = {
|
140 |
| - .op_byte = 0xABU, |
141 | 123 | .op_type = VIE_OP_TYPE_STOS,
|
142 | 124 | .op_flags = VIE_OP_F_NO_MODRM | VIE_OP_F_NO_GLA_VERIFICATION
|
143 | 125 | },
|
144 | 126 | [0xC6] = {
|
145 | 127 | /* XXX Group 11 extended opcode - not just MOV */
|
146 |
| - .op_byte = 0xC6U, |
147 | 128 | .op_type = VIE_OP_TYPE_MOV,
|
148 | 129 | .op_flags = VIE_OP_F_IMM8,
|
149 | 130 | },
|
150 | 131 | [0xC7] = {
|
151 |
| - .op_byte = 0xC7U, |
152 | 132 | .op_type = VIE_OP_TYPE_MOV,
|
153 | 133 | .op_flags = VIE_OP_F_IMM,
|
154 | 134 | },
|
155 | 135 | [0x23] = {
|
156 |
| - .op_byte = 0x23U, |
157 | 136 | .op_type = VIE_OP_TYPE_AND,
|
158 | 137 | },
|
159 | 138 | [0x80] = {
|
160 | 139 | /* Group 1 extended opcode */
|
161 |
| - .op_byte = 0x80U, |
162 | 140 | .op_type = VIE_OP_TYPE_GROUP1,
|
163 | 141 | .op_flags = VIE_OP_F_IMM8,
|
164 | 142 | },
|
165 | 143 | [0x81] = {
|
166 | 144 | /* Group 1 extended opcode */
|
167 |
| - .op_byte = 0x81U, |
168 | 145 | .op_type = VIE_OP_TYPE_GROUP1,
|
169 | 146 | .op_flags = VIE_OP_F_IMM,
|
170 | 147 | },
|
171 | 148 | [0x83] = {
|
172 | 149 | /* Group 1 extended opcode */
|
173 |
| - .op_byte = 0x83U, |
174 | 150 | .op_type = VIE_OP_TYPE_GROUP1,
|
175 | 151 | .op_flags = VIE_OP_F_IMM8,
|
176 | 152 | },
|
177 | 153 | [0x84] = {
|
178 |
| - .op_byte = 0x84U, |
179 | 154 | .op_type = VIE_OP_TYPE_TEST,
|
180 | 155 | },
|
181 | 156 | [0x85] = {
|
182 |
| - .op_byte = 0x85U, |
183 | 157 | .op_type = VIE_OP_TYPE_TEST,
|
184 | 158 | },
|
185 | 159 | [0x08] = {
|
186 |
| - .op_byte = 0x08U, |
187 | 160 | .op_type = VIE_OP_TYPE_OR,
|
188 | 161 | },
|
189 | 162 | [0x09] = {
|
190 |
| - .op_byte = 0x09U, |
191 | 163 | .op_type = VIE_OP_TYPE_OR,
|
192 | 164 | },
|
193 | 165 | [0x8F] = {
|
194 | 166 | /* XXX Group 1A extended opcode - not just POP */
|
195 |
| - .op_byte = 0x8FU, |
196 | 167 | .op_type = VIE_OP_TYPE_POP,
|
197 | 168 | },
|
198 | 169 | [0xFF] = {
|
199 | 170 | /* XXX Group 5 extended opcode - not just PUSH */
|
200 |
| - .op_byte = 0xFFU, |
201 | 171 | .op_type = VIE_OP_TYPE_PUSH,
|
202 | 172 | }
|
203 | 173 | };
|
@@ -398,7 +368,7 @@ emulate_mov(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
398 | 368 |
|
399 | 369 | size = vie->opsize;
|
400 | 370 | error = -EINVAL;
|
401 |
| - switch (vie->op.op_byte) { |
| 371 | + switch (vie->opcode) { |
402 | 372 | case 0x88U:
|
403 | 373 | /*
|
404 | 374 | * MOV byte from reg (ModRM:reg) to mem (ModRM:r/m)
|
@@ -524,7 +494,7 @@ emulate_movx(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
524 | 494 | size = vie->opsize;
|
525 | 495 | error = -EINVAL;
|
526 | 496 |
|
527 |
| - switch (vie->op.op_byte) { |
| 497 | + switch (vie->opcode) { |
528 | 498 | case 0xB6U:
|
529 | 499 | /*
|
530 | 500 | * MOV and zero extend byte from mem (ModRM:r/m) to
|
@@ -675,7 +645,7 @@ emulate_movs(struct vcpu *vcpu, __unused uint64_t gpa, struct instr_emul_vie *vi
|
675 | 645 | uint8_t opsize;
|
676 | 646 | enum cpu_reg_name seg;
|
677 | 647 |
|
678 |
| - opsize = (vie->op.op_byte == 0xA4U) ? 1U : vie->opsize; |
| 648 | + opsize = (vie->opcode == 0xA4U) ? 1U : vie->opsize; |
679 | 649 | error = 0;
|
680 | 650 |
|
681 | 651 | /*
|
@@ -762,7 +732,7 @@ emulate_stos(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
762 | 732 | uint64_t val;
|
763 | 733 | uint64_t rcx, rdi, rflags;
|
764 | 734 |
|
765 |
| - opsize = (vie->op.op_byte == 0xAAU) ? 1U : vie->opsize; |
| 735 | + opsize = (vie->opcode == 0xAAU) ? 1U : vie->opsize; |
766 | 736 | repeat = vie->repz_present | vie->repnz_present;
|
767 | 737 |
|
768 | 738 | if (repeat != 0) {
|
@@ -825,7 +795,7 @@ emulate_test(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
825 | 795 | size = vie->opsize;
|
826 | 796 | error = -EINVAL;
|
827 | 797 |
|
828 |
| - switch (vie->op.op_byte) { |
| 798 | + switch (vie->opcode) { |
829 | 799 | case 0x84U:
|
830 | 800 | /*
|
831 | 801 | * 84/r test r8, r/m8
|
@@ -891,7 +861,7 @@ emulate_and(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
891 | 861 | size = vie->opsize;
|
892 | 862 | error = -EINVAL;
|
893 | 863 |
|
894 |
| - switch (vie->op.op_byte) { |
| 864 | + switch (vie->opcode) { |
895 | 865 | case 0x23U:
|
896 | 866 | /*
|
897 | 867 | * AND reg (ModRM:reg) and mem (ModRM:r/m) and store the
|
@@ -980,7 +950,7 @@ emulate_or(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
980 | 950 | size = vie->opsize;
|
981 | 951 | error = -EINVAL;
|
982 | 952 |
|
983 |
| - switch (vie->op.op_byte) { |
| 953 | + switch (vie->opcode) { |
984 | 954 | case 0x81U:
|
985 | 955 | case 0x83U:
|
986 | 956 | /*
|
@@ -1070,7 +1040,7 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
1070 | 1040 | enum cpu_reg_name reg;
|
1071 | 1041 |
|
1072 | 1042 | size = vie->opsize;
|
1073 |
| - switch (vie->op.op_byte) { |
| 1043 | + switch (vie->opcode) { |
1074 | 1044 | case 0x39U:
|
1075 | 1045 | case 0x3BU:
|
1076 | 1046 | /*
|
@@ -1101,7 +1071,7 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
1101 | 1071 | return error;
|
1102 | 1072 | }
|
1103 | 1073 |
|
1104 |
| - if (vie->op.op_byte == 0x3BU) { |
| 1074 | + if (vie->opcode == 0x3BU) { |
1105 | 1075 | op1 = regop;
|
1106 | 1076 | op2 = memop;
|
1107 | 1077 | } else {
|
@@ -1136,7 +1106,7 @@ emulate_cmp(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
1136 | 1106 | * the status flags.
|
1137 | 1107 | *
|
1138 | 1108 | */
|
1139 |
| - if (vie->op.op_byte == 0x80U) { |
| 1109 | + if (vie->opcode == 0x80U) { |
1140 | 1110 | size = 1U;
|
1141 | 1111 | }
|
1142 | 1112 |
|
@@ -1170,7 +1140,7 @@ emulate_sub(struct vcpu *vcpu, uint64_t gpa, struct instr_emul_vie *vie,
|
1170 | 1140 | size = vie->opsize;
|
1171 | 1141 | error = -EINVAL;
|
1172 | 1142 |
|
1173 |
| - switch (vie->op.op_byte) { |
| 1143 | + switch (vie->opcode) { |
1174 | 1144 | case 0x2BU:
|
1175 | 1145 | /*
|
1176 | 1146 | * SUB r/m from r and store the result in r
|
@@ -1850,6 +1820,7 @@ decode_opcode(struct instr_emul_vie *vie)
|
1850 | 1820 | return -1;
|
1851 | 1821 | }
|
1852 | 1822 |
|
| 1823 | + vie->opcode = x; |
1853 | 1824 | vie->op = one_byte_opcodes[x];
|
1854 | 1825 |
|
1855 | 1826 | if (vie->op.op_type == VIE_OP_TYPE_NONE) {
|
|
0 commit comments