diff options
author | Avi Kivity <avi@qumranet.com> | 2008-01-18 05:58:04 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-04-27 04:53:14 -0400 |
commit | 7d858a19efe5844a98e060931570359b70dea6d1 (patch) | |
tree | 62ee800fb0f1a8a976ab47b015717b34636f3275 /arch/x86/kvm | |
parent | 43bb19cd3398d3f544d8e2d6ed6c5c5d7b4e5819 (diff) |
KVM: x86 emulator: Group decoding for group 3
This adds group decoding support for opcodes 0xf6, 0xf7 (group 3).
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 34 |
1 files changed, 10 insertions, 24 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index cf1ce7c316a9..52e65ae37f06 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -70,7 +70,7 @@ | |||
70 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ | 70 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ |
71 | 71 | ||
72 | enum { | 72 | enum { |
73 | Group1A, | 73 | Group1A, Group3_Byte, Group3, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static u16 opcode_table[256] = { | 76 | static u16 opcode_table[256] = { |
@@ -171,8 +171,7 @@ static u16 opcode_table[256] = { | |||
171 | 0, 0, 0, 0, | 171 | 0, 0, 0, 0, |
172 | /* 0xF0 - 0xF7 */ | 172 | /* 0xF0 - 0xF7 */ |
173 | 0, 0, 0, 0, | 173 | 0, 0, 0, 0, |
174 | ImplicitOps, ImplicitOps, | 174 | ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, |
175 | ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, | ||
176 | /* 0xF8 - 0xFF */ | 175 | /* 0xF8 - 0xFF */ |
177 | ImplicitOps, 0, ImplicitOps, ImplicitOps, | 176 | ImplicitOps, 0, ImplicitOps, ImplicitOps, |
178 | 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM | 177 | 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM |
@@ -239,6 +238,14 @@ static u16 twobyte_table[256] = { | |||
239 | static u16 group_table[] = { | 238 | static u16 group_table[] = { |
240 | [Group1A*8] = | 239 | [Group1A*8] = |
241 | DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, | 240 | DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, |
241 | [Group3_Byte*8] = | ||
242 | ByteOp | SrcImm | DstMem | ModRM, 0, | ||
243 | ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, | ||
244 | 0, 0, 0, 0, | ||
245 | [Group3*8] = | ||
246 | DstMem | SrcImm | ModRM | SrcImm, 0, | ||
247 | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, | ||
248 | 0, 0, 0, 0, | ||
242 | }; | 249 | }; |
243 | 250 | ||
244 | static u16 group2_table[] = { | 251 | static u16 group2_table[] = { |
@@ -1070,26 +1077,6 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, | |||
1070 | 1077 | ||
1071 | switch (c->modrm_reg) { | 1078 | switch (c->modrm_reg) { |
1072 | case 0 ... 1: /* test */ | 1079 | case 0 ... 1: /* test */ |
1073 | /* | ||
1074 | * Special case in Grp3: test has an immediate | ||
1075 | * source operand. | ||
1076 | */ | ||
1077 | c->src.type = OP_IMM; | ||
1078 | c->src.ptr = (unsigned long *)c->eip; | ||
1079 | c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
1080 | if (c->src.bytes == 8) | ||
1081 | c->src.bytes = 4; | ||
1082 | switch (c->src.bytes) { | ||
1083 | case 1: | ||
1084 | c->src.val = insn_fetch(s8, 1, c->eip); | ||
1085 | break; | ||
1086 | case 2: | ||
1087 | c->src.val = insn_fetch(s16, 2, c->eip); | ||
1088 | break; | ||
1089 | case 4: | ||
1090 | c->src.val = insn_fetch(s32, 4, c->eip); | ||
1091 | break; | ||
1092 | } | ||
1093 | emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags); | 1080 | emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags); |
1094 | break; | 1081 | break; |
1095 | case 2: /* not */ | 1082 | case 2: /* not */ |
@@ -1103,7 +1090,6 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, | |||
1103 | rc = X86EMUL_UNHANDLEABLE; | 1090 | rc = X86EMUL_UNHANDLEABLE; |
1104 | break; | 1091 | break; |
1105 | } | 1092 | } |
1106 | done: | ||
1107 | return rc; | 1093 | return rc; |
1108 | } | 1094 | } |
1109 | 1095 | ||