diff options
| author | Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net> | 2008-12-04 08:26:42 -0500 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:55:42 -0500 |
| commit | 0dc8d10f7d848b63c8d32cf6fd31ba7def792ac9 (patch) | |
| tree | 82c1a42032974305b3ebca01891c07a2a148287c | |
| parent | 45ed60b371aeae6ed80f7e9d594a5e6412edc176 (diff) | |
KVM: x86 emulator: add Src2 decode set
Instruction like shld has three operands, so we need to add a Src2
decode set. We start with Src2None, Src2CL, and Src2ImmByte, Src2One to
support shld/shrd and we will expand it later.
Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Signed-off-by: Avi Kivity <avi@redhat.com>
| -rw-r--r-- | arch/x86/include/asm/kvm_x86_emulate.h | 1 | ||||
| -rw-r--r-- | arch/x86/kvm/x86_emulate.c | 29 |
2 files changed, 30 insertions, 0 deletions
diff --git a/arch/x86/include/asm/kvm_x86_emulate.h b/arch/x86/include/asm/kvm_x86_emulate.h index 16a002655f31..6a159732881a 100644 --- a/arch/x86/include/asm/kvm_x86_emulate.h +++ b/arch/x86/include/asm/kvm_x86_emulate.h | |||
| @@ -123,6 +123,7 @@ struct decode_cache { | |||
| 123 | u8 ad_bytes; | 123 | u8 ad_bytes; |
| 124 | u8 rex_prefix; | 124 | u8 rex_prefix; |
| 125 | struct operand src; | 125 | struct operand src; |
| 126 | struct operand src2; | ||
| 126 | struct operand dst; | 127 | struct operand dst; |
| 127 | bool has_seg_override; | 128 | bool has_seg_override; |
| 128 | u8 seg_override; | 129 | u8 seg_override; |
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 7a07ca46c8ae..7f5cd62362c5 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
| @@ -70,6 +70,12 @@ | |||
| 70 | #define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ | 70 | #define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */ |
| 71 | #define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ | 71 | #define GroupDual (1<<15) /* Alternate decoding of mod == 3 */ |
| 72 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ | 72 | #define GroupMask 0xff /* Group number stored in bits 0:7 */ |
| 73 | /* Source 2 operand type */ | ||
| 74 | #define Src2None (0<<29) | ||
| 75 | #define Src2CL (1<<29) | ||
| 76 | #define Src2ImmByte (2<<29) | ||
| 77 | #define Src2One (3<<29) | ||
| 78 | #define Src2Mask (7<<29) | ||
| 73 | 79 | ||
| 74 | enum { | 80 | enum { |
| 75 | Group1_80, Group1_81, Group1_82, Group1_83, | 81 | Group1_80, Group1_81, Group1_82, Group1_83, |
| @@ -1000,6 +1006,29 @@ done_prefixes: | |||
| 1000 | break; | 1006 | break; |
| 1001 | } | 1007 | } |
| 1002 | 1008 | ||
| 1009 | /* | ||
| 1010 | * Decode and fetch the second source operand: register, memory | ||
| 1011 | * or immediate. | ||
| 1012 | */ | ||
| 1013 | switch (c->d & Src2Mask) { | ||
| 1014 | case Src2None: | ||
| 1015 | break; | ||
| 1016 | case Src2CL: | ||
| 1017 | c->src2.bytes = 1; | ||
| 1018 | c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8; | ||
| 1019 | break; | ||
| 1020 | case Src2ImmByte: | ||
| 1021 | c->src2.type = OP_IMM; | ||
| 1022 | c->src2.ptr = (unsigned long *)c->eip; | ||
| 1023 | c->src2.bytes = 1; | ||
| 1024 | c->src2.val = insn_fetch(u8, 1, c->eip); | ||
| 1025 | break; | ||
| 1026 | case Src2One: | ||
| 1027 | c->src2.bytes = 1; | ||
| 1028 | c->src2.val = 1; | ||
| 1029 | break; | ||
| 1030 | } | ||
| 1031 | |||
| 1003 | /* Decode and fetch the destination operand: register or memory. */ | 1032 | /* Decode and fetch the destination operand: register or memory. */ |
| 1004 | switch (c->d & DstMask) { | 1033 | switch (c->d & DstMask) { |
| 1005 | case ImplicitOps: | 1034 | case ImplicitOps: |
