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 /arch | |
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>
Diffstat (limited to 'arch')
-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: |