diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-04-12 06:36:30 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:40 -0400 |
commit | b2833e3cdebfe3ea4d0d1d3ce4d2ff1c42a4f8f4 (patch) | |
tree | 5c1989ea333547e5aec85371a237c602b41c74e8 | |
parent | 782b877c8073a9ef307ad6638ee472b8336b2b85 (diff) |
KVM: x86 emulator: Complete short/near jcc decoding in decode stage
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 42 |
1 files changed, 10 insertions, 32 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 8779cf233a83..14b8ee2c09e9 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -136,11 +136,11 @@ static u32 opcode_table[256] = { | |||
136 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */ | 136 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */ |
137 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */ | 137 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */ |
138 | /* 0x70 - 0x77 */ | 138 | /* 0x70 - 0x77 */ |
139 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, | 139 | SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, |
140 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, | 140 | SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, |
141 | /* 0x78 - 0x7F */ | 141 | /* 0x78 - 0x7F */ |
142 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, | 142 | SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, |
143 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, | 143 | SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, |
144 | /* 0x80 - 0x87 */ | 144 | /* 0x80 - 0x87 */ |
145 | Group | Group1_80, Group | Group1_81, | 145 | Group | Group1_80, Group | Group1_81, |
146 | Group | Group1_82, Group | Group1_83, | 146 | Group | Group1_82, Group | Group1_83, |
@@ -232,10 +232,8 @@ static u32 twobyte_table[256] = { | |||
232 | /* 0x70 - 0x7F */ | 232 | /* 0x70 - 0x7F */ |
233 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 233 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
234 | /* 0x80 - 0x8F */ | 234 | /* 0x80 - 0x8F */ |
235 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, | 235 | SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, |
236 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, | 236 | SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, |
237 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, | ||
238 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, | ||
239 | /* 0x90 - 0x9F */ | 237 | /* 0x90 - 0x9F */ |
240 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 238 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
241 | /* 0xA0 - 0xA7 */ | 239 | /* 0xA0 - 0xA7 */ |
@@ -1539,13 +1537,10 @@ special_insn: | |||
1539 | return -1; | 1537 | return -1; |
1540 | } | 1538 | } |
1541 | return 0; | 1539 | return 0; |
1542 | case 0x70 ... 0x7f: /* jcc (short) */ { | 1540 | case 0x70 ... 0x7f: /* jcc (short) */ |
1543 | int rel = insn_fetch(s8, 1, c->eip); | ||
1544 | |||
1545 | if (test_cc(c->b, ctxt->eflags)) | 1541 | if (test_cc(c->b, ctxt->eflags)) |
1546 | jmp_rel(c, rel); | 1542 | jmp_rel(c, c->src.val); |
1547 | break; | 1543 | break; |
1548 | } | ||
1549 | case 0x80 ... 0x83: /* Grp1 */ | 1544 | case 0x80 ... 0x83: /* Grp1 */ |
1550 | switch (c->modrm_reg) { | 1545 | switch (c->modrm_reg) { |
1551 | case 0: | 1546 | case 0: |
@@ -2031,28 +2026,11 @@ twobyte_insn: | |||
2031 | if (!test_cc(c->b, ctxt->eflags)) | 2026 | if (!test_cc(c->b, ctxt->eflags)) |
2032 | c->dst.type = OP_NONE; /* no writeback */ | 2027 | c->dst.type = OP_NONE; /* no writeback */ |
2033 | break; | 2028 | break; |
2034 | case 0x80 ... 0x8f: /* jnz rel, etc*/ { | 2029 | case 0x80 ... 0x8f: /* jnz rel, etc*/ |
2035 | long int rel; | ||
2036 | |||
2037 | switch (c->op_bytes) { | ||
2038 | case 2: | ||
2039 | rel = insn_fetch(s16, 2, c->eip); | ||
2040 | break; | ||
2041 | case 4: | ||
2042 | rel = insn_fetch(s32, 4, c->eip); | ||
2043 | break; | ||
2044 | case 8: | ||
2045 | rel = insn_fetch(s64, 8, c->eip); | ||
2046 | break; | ||
2047 | default: | ||
2048 | DPRINTF("jnz: Invalid op_bytes\n"); | ||
2049 | goto cannot_emulate; | ||
2050 | } | ||
2051 | if (test_cc(c->b, ctxt->eflags)) | 2030 | if (test_cc(c->b, ctxt->eflags)) |
2052 | jmp_rel(c, rel); | 2031 | jmp_rel(c, c->src.val); |
2053 | c->dst.type = OP_NONE; | 2032 | c->dst.type = OP_NONE; |
2054 | break; | 2033 | break; |
2055 | } | ||
2056 | case 0xa3: | 2034 | case 0xa3: |
2057 | bt: /* bt */ | 2035 | bt: /* bt */ |
2058 | c->dst.type = OP_NONE; | 2036 | c->dst.type = OP_NONE; |