diff options
Diffstat (limited to 'target/i386/hvf')
| -rw-r--r-- | target/i386/hvf/hvf-i386.h | 4 | ||||
| -rw-r--r-- | target/i386/hvf/hvf.c | 57 | ||||
| -rw-r--r-- | target/i386/hvf/meson.build | 3 | ||||
| -rw-r--r-- | target/i386/hvf/vmx.h | 2 | ||||
| -rw-r--r-- | target/i386/hvf/x86.c | 4 | ||||
| -rw-r--r-- | target/i386/hvf/x86.h | 289 | ||||
| -rw-r--r-- | target/i386/hvf/x86_cpuid.c | 2 | ||||
| -rw-r--r-- | target/i386/hvf/x86_decode.c | 2204 | ||||
| -rw-r--r-- | target/i386/hvf/x86_decode.h | 325 | ||||
| -rw-r--r-- | target/i386/hvf/x86_descr.h | 2 | ||||
| -rw-r--r-- | target/i386/hvf/x86_emu.c | 1259 | ||||
| -rw-r--r-- | target/i386/hvf/x86_emu.h | 45 | ||||
| -rw-r--r-- | target/i386/hvf/x86_flags.c | 313 | ||||
| -rw-r--r-- | target/i386/hvf/x86_flags.h | 81 | ||||
| -rw-r--r-- | target/i386/hvf/x86_mmu.c | 2 | ||||
| -rw-r--r-- | target/i386/hvf/x86_task.c | 6 | ||||
| -rw-r--r-- | target/i386/hvf/x86hvf.c | 2 |
17 files changed, 54 insertions, 4546 deletions
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h index 044ad236ae..8c42ae6b01 100644 --- a/target/i386/hvf/hvf-i386.h +++ b/target/i386/hvf/hvf-i386.h @@ -19,8 +19,8 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, int reg); void hvf_handle_io(CPUState *, uint16_t, void *, int, int, int); -void hvf_simulate_rdmsr(CPUX86State *env); -void hvf_simulate_wrmsr(CPUX86State *env); +void hvf_simulate_rdmsr(CPUState *cpu); +void hvf_simulate_wrmsr(CPUState *cpu); /* Host specific functions */ int hvf_inject_interrupt(CPUArchState *env, int vector); diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 9ba0e04ac7..23ebf2550a 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -59,12 +59,12 @@ #include "hvf-i386.h" #include "vmcs.h" #include "vmx.h" -#include "x86.h" +#include "emulate/x86.h" #include "x86_descr.h" -#include "x86_flags.h" +#include "emulate/x86_flags.h" #include "x86_mmu.h" -#include "x86_decode.h" -#include "x86_emu.h" +#include "emulate/x86_decode.h" +#include "emulate/x86_emu.h" #include "x86_task.h" #include "x86hvf.h" @@ -168,7 +168,7 @@ void hvf_arch_vcpu_destroy(CPUState *cpu) X86CPU *x86_cpu = X86_CPU(cpu); CPUX86State *env = &x86_cpu->env; - g_free(env->hvf_mmio_buf); + g_free(env->emu_mmio_buf); } static void init_tsc_freq(CPUX86State *env) @@ -229,6 +229,33 @@ hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range) return hv_vm_create(HV_VM_DEFAULT); } +static void hvf_read_segment_descriptor(CPUState *s, struct x86_segment_descriptor *desc, + X86Seg seg) +{ + struct vmx_segment vmx_segment; + vmx_read_segment_descriptor(s, &vmx_segment, seg); + vmx_segment_to_x86_descriptor(s, &vmx_segment, desc); +} + +static void hvf_read_mem(CPUState *cpu, void *data, target_ulong gva, int bytes) +{ + vmx_read_mem(cpu, data, gva, bytes); +} + +static void hvf_write_mem(CPUState *cpu, void *data, target_ulong gva, int bytes) +{ + vmx_write_mem(cpu, gva, data, bytes); +} + +static const struct x86_emul_ops hvf_x86_emul_ops = { + .read_mem = hvf_read_mem, + .write_mem = hvf_write_mem, + .read_segment_descriptor = hvf_read_segment_descriptor, + .handle_io = hvf_handle_io, + .simulate_rdmsr = hvf_simulate_rdmsr, + .simulate_wrmsr = hvf_simulate_wrmsr, +}; + int hvf_arch_init_vcpu(CPUState *cpu) { X86CPU *x86cpu = X86_CPU(cpu); @@ -237,13 +264,13 @@ int hvf_arch_init_vcpu(CPUState *cpu) int r; uint64_t reqCap; - init_emu(); + init_emu(&hvf_x86_emul_ops); init_decoder(); if (hvf_state->hvf_caps == NULL) { hvf_state->hvf_caps = g_new0(struct hvf_vcpu_caps, 1); } - env->hvf_mmio_buf = g_new(char, 4096); + env->emu_mmio_buf = g_new(char, 4096); if (x86cpu->vmware_cpuid_freq) { init_tsc_freq(env); @@ -481,10 +508,10 @@ void hvf_store_regs(CPUState *cs) macvm_set_rip(cs, env->eip); } -void hvf_simulate_rdmsr(CPUX86State *env) +void hvf_simulate_rdmsr(CPUState *cs) { - X86CPU *cpu = env_archcpu(env); - CPUState *cs = env_cpu(env); + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; uint32_t msr = ECX(env); uint64_t val = 0; @@ -586,10 +613,10 @@ void hvf_simulate_rdmsr(CPUX86State *env) RDX(env) = (uint32_t)(val >> 32); } -void hvf_simulate_wrmsr(CPUX86State *env) +void hvf_simulate_wrmsr(CPUState *cs) { - X86CPU *cpu = env_archcpu(env); - CPUState *cs = env_cpu(env); + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; uint32_t msr = ECX(env); uint64_t data = ((uint64_t)EDX(env) << 32) | EAX(env); @@ -875,9 +902,9 @@ int hvf_vcpu_exec(CPUState *cpu) { hvf_load_regs(cpu); if (exit_reason == EXIT_REASON_RDMSR) { - hvf_simulate_rdmsr(env); + hvf_simulate_rdmsr(cpu); } else { - hvf_simulate_wrmsr(env); + hvf_simulate_wrmsr(cpu); } env->eip += ins_len; hvf_store_regs(cpu); diff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build index 05c3c8cf18..519d190f0e 100644 --- a/target/i386/hvf/meson.build +++ b/target/i386/hvf/meson.build @@ -2,10 +2,7 @@ i386_system_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files( 'hvf.c', 'x86.c', 'x86_cpuid.c', - 'x86_decode.c', 'x86_descr.c', - 'x86_emu.c', - 'x86_flags.c', 'x86_mmu.c', 'x86_task.c', 'x86hvf.c', diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h index 80ce26279b..3c56afc9d3 100644 --- a/target/i386/hvf/vmx.h +++ b/target/i386/hvf/vmx.h @@ -29,7 +29,7 @@ #include <Hypervisor/hv_vmx.h> #include "vmcs.h" #include "cpu.h" -#include "x86.h" +#include "emulate/x86.h" #include "system/hvf.h" #include "system/hvf_int.h" diff --git a/target/i386/hvf/x86.c b/target/i386/hvf/x86.c index a0ede13886..5c75ec9a00 100644 --- a/target/i386/hvf/x86.c +++ b/target/i386/hvf/x86.c @@ -19,8 +19,8 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "x86_decode.h" -#include "x86_emu.h" +#include "emulate/x86_decode.h" +#include "emulate/x86_emu.h" #include "vmcs.h" #include "vmx.h" #include "x86_mmu.h" diff --git a/target/i386/hvf/x86.h b/target/i386/hvf/x86.h deleted file mode 100644 index 063cd0b83e..0000000000 --- a/target/i386/hvf/x86.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2016 Veertu Inc, - * Copyright (C) 2017 Veertu Inc, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef HVF_X86_H -#define HVF_X86_H - -typedef struct x86_register { - union { - struct { - uint64_t rrx; /* full 64 bit */ - }; - struct { - uint32_t erx; /* low 32 bit part */ - uint32_t hi32_unused1; - }; - struct { - uint16_t rx; /* low 16 bit part */ - uint16_t hi16_unused1; - uint32_t hi32_unused2; - }; - struct { - uint8_t lx; /* low 8 bit part */ - uint8_t hx; /* high 8 bit */ - uint16_t hi16_unused2; - uint32_t hi32_unused3; - }; - }; -} __attribute__ ((__packed__)) x86_register; - -/* 16 bit Task State Segment */ -typedef struct x86_tss_segment16 { - uint16_t link; - uint16_t sp0; - uint16_t ss0; - uint32_t sp1; - uint16_t ss1; - uint32_t sp2; - uint16_t ss2; - uint16_t ip; - uint16_t flags; - uint16_t ax; - uint16_t cx; - uint16_t dx; - uint16_t bx; - uint16_t sp; - uint16_t bp; - uint16_t si; - uint16_t di; - uint16_t es; - uint16_t cs; - uint16_t ss; - uint16_t ds; - uint16_t ldtr; -} __attribute__((packed)) x86_tss_segment16; - -/* 32 bit Task State Segment */ -typedef struct x86_tss_segment32 { - uint32_t prev_tss; - uint32_t esp0; - uint32_t ss0; - uint32_t esp1; - uint32_t ss1; - uint32_t esp2; - uint32_t ss2; - uint32_t cr3; - uint32_t eip; - uint32_t eflags; - uint32_t eax; - uint32_t ecx; - uint32_t edx; - uint32_t ebx; - uint32_t esp; - uint32_t ebp; - uint32_t esi; - uint32_t edi; - uint32_t es; - uint32_t cs; - uint32_t ss; - uint32_t ds; - uint32_t fs; - uint32_t gs; - uint32_t ldt; - uint16_t trap; - uint16_t iomap_base; -} __attribute__ ((__packed__)) x86_tss_segment32; - -/* 64 bit Task State Segment */ -typedef struct x86_tss_segment64 { - uint32_t unused; - uint64_t rsp0; - uint64_t rsp1; - uint64_t rsp2; - uint64_t unused1; - uint64_t ist1; - uint64_t ist2; - uint64_t ist3; - uint64_t ist4; - uint64_t ist5; - uint64_t ist6; - uint64_t ist7; - uint64_t unused2; - uint16_t unused3; - uint16_t iomap_base; -} __attribute__ ((__packed__)) x86_tss_segment64; - -/* segment descriptors */ -typedef struct x86_segment_descriptor { - uint64_t limit0:16; - uint64_t base0:16; - uint64_t base1:8; - uint64_t type:4; - uint64_t s:1; - uint64_t dpl:2; - uint64_t p:1; - uint64_t limit1:4; - uint64_t avl:1; - uint64_t l:1; - uint64_t db:1; - uint64_t g:1; - uint64_t base2:8; -} __attribute__ ((__packed__)) x86_segment_descriptor; - -static inline uint32_t x86_segment_base(x86_segment_descriptor *desc) -{ - return (uint32_t)((desc->base2 << 24) | (desc->base1 << 16) | desc->base0); -} - -static inline void x86_set_segment_base(x86_segment_descriptor *desc, - uint32_t base) -{ - desc->base2 = base >> 24; - desc->base1 = (base >> 16) & 0xff; - desc->base0 = base & 0xffff; -} - -static inline uint32_t x86_segment_limit(x86_segment_descriptor *desc) -{ - uint32_t limit = (uint32_t)((desc->limit1 << 16) | desc->limit0); - if (desc->g) { - return (limit << 12) | 0xfff; - } - return limit; -} - -static inline void x86_set_segment_limit(x86_segment_descriptor *desc, - uint32_t limit) -{ - desc->limit0 = limit & 0xffff; - desc->limit1 = limit >> 16; -} - -typedef struct x86_call_gate { - uint64_t offset0:16; - uint64_t selector:16; - uint64_t param_count:4; - uint64_t reserved:3; - uint64_t type:4; - uint64_t dpl:1; - uint64_t p:1; - uint64_t offset1:16; -} __attribute__ ((__packed__)) x86_call_gate; - -static inline uint32_t x86_call_gate_offset(x86_call_gate *gate) -{ - return (uint32_t)((gate->offset1 << 16) | gate->offset0); -} - -#define GDT_SEL 0 -#define LDT_SEL 1 - -typedef struct x86_segment_selector { - union { - uint16_t sel; - struct { - uint16_t rpl:2; - uint16_t ti:1; - uint16_t index:13; - }; - }; -} __attribute__ ((__packed__)) x86_segment_selector; - -/* useful register access macros */ -#define x86_reg(cpu, reg) ((x86_register *) &cpu->regs[reg]) - -#define RRX(cpu, reg) (x86_reg(cpu, reg)->rrx) -#define RAX(cpu) RRX(cpu, R_EAX) -#define RCX(cpu) RRX(cpu, R_ECX) -#define RDX(cpu) RRX(cpu, R_EDX) -#define RBX(cpu) RRX(cpu, R_EBX) -#define RSP(cpu) RRX(cpu, R_ESP) -#define RBP(cpu) RRX(cpu, R_EBP) -#define RSI(cpu) RRX(cpu, R_ESI) -#define RDI(cpu) RRX(cpu, R_EDI) -#define R8(cpu) RRX(cpu, R_R8) -#define R9(cpu) RRX(cpu, R_R9) -#define R10(cpu) RRX(cpu, R_R10) -#define R11(cpu) RRX(cpu, R_R11) -#define R12(cpu) RRX(cpu, R_R12) -#define R13(cpu) RRX(cpu, R_R13) -#define R14(cpu) RRX(cpu, R_R14) -#define R15(cpu) RRX(cpu, R_R15) - -#define ERX(cpu, reg) (x86_reg(cpu, reg)->erx) -#define EAX(cpu) ERX(cpu, R_EAX) -#define ECX(cpu) ERX(cpu, R_ECX) -#define EDX(cpu) ERX(cpu, R_EDX) -#define EBX(cpu) ERX(cpu, R_EBX) -#define ESP(cpu) ERX(cpu, R_ESP) -#define EBP(cpu) ERX(cpu, R_EBP) -#define ESI(cpu) ERX(cpu, R_ESI) -#define EDI(cpu) ERX(cpu, R_EDI) - -#define RX(cpu, reg) (x86_reg(cpu, reg)->rx) -#define AX(cpu) RX(cpu, R_EAX) -#define CX(cpu) RX(cpu, R_ECX) -#define DX(cpu) RX(cpu, R_EDX) -#define BP(cpu) RX(cpu, R_EBP) -#define SP(cpu) RX(cpu, R_ESP) -#define BX(cpu) RX(cpu, R_EBX) -#define SI(cpu) RX(cpu, R_ESI) -#define DI(cpu) RX(cpu, R_EDI) - -#define RL(cpu, reg) (x86_reg(cpu, reg)->lx) -#define AL(cpu) RL(cpu, R_EAX) -#define CL(cpu) RL(cpu, R_ECX) -#define DL(cpu) RL(cpu, R_EDX) -#define BL(cpu) RL(cpu, R_EBX) - -#define RH(cpu, reg) (x86_reg(cpu, reg)->hx) -#define AH(cpu) RH(cpu, R_EAX) -#define CH(cpu) RH(cpu, R_ECX) -#define DH(cpu) RH(cpu, R_EDX) -#define BH(cpu) RH(cpu, R_EBX) - -/* deal with GDT/LDT descriptors in memory */ -bool x86_read_segment_descriptor(CPUState *cpu, - struct x86_segment_descriptor *desc, - x86_segment_selector sel); -bool x86_write_segment_descriptor(CPUState *cpu, - struct x86_segment_descriptor *desc, - x86_segment_selector sel); - -bool x86_read_call_gate(CPUState *cpu, struct x86_call_gate *idt_desc, - int gate); - -/* helpers */ -bool x86_is_protected(CPUState *cpu); -bool x86_is_real(CPUState *cpu); -bool x86_is_v8086(CPUState *cpu); -bool x86_is_long_mode(CPUState *cpu); -bool x86_is_long64_mode(CPUState *cpu); -bool x86_is_paging_mode(CPUState *cpu); -bool x86_is_pae_enabled(CPUState *cpu); - -enum X86Seg; -target_ulong linear_addr(CPUState *cpu, target_ulong addr, enum X86Seg seg); -target_ulong linear_addr_size(CPUState *cpu, target_ulong addr, int size, - enum X86Seg seg); -target_ulong linear_rip(CPUState *cpu, target_ulong rip); - -static inline uint64_t rdtscp(void) -{ - uint64_t tsc; - __asm__ __volatile__("rdtscp; " /* serializing read of tsc */ - "shl $32,%%rdx; " /* shift higher 32 bits stored in rdx up */ - "or %%rdx,%%rax" /* and or onto rax */ - : "=a"(tsc) /* output to tsc variable */ - : - : "%rcx", "%rdx"); /* rcx and rdx are clobbered */ - - return tsc; -} - -#endif diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c index ae836f65cc..fa131b18c6 100644 --- a/target/i386/hvf/x86_cpuid.c +++ b/target/i386/hvf/x86_cpuid.c @@ -24,7 +24,7 @@ #include "qemu/cpuid.h" #include "host/cpuinfo.h" #include "cpu.h" -#include "x86.h" +#include "emulate/x86.h" #include "vmx.h" #include "system/hvf.h" #include "hvf-i386.h" diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c deleted file mode 100644 index 5fea2dd3cc..0000000000 --- a/target/i386/hvf/x86_decode.c +++ /dev/null @@ -1,2204 +0,0 @@ -/* - * Copyright (C) 2016 Veertu Inc, - * Copyright (C) 2017 Google Inc, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "qemu/osdep.h" - -#include "panic.h" -#include "x86_decode.h" -#include "vmx.h" -#include "x86_mmu.h" -#include "x86_descr.h" - -#define OPCODE_ESCAPE 0xf - -static void decode_invalid(CPUX86State *env, struct x86_decode *decode) -{ - printf("%llx: failed to decode instruction ", env->eip); - for (int i = 0; i < decode->opcode_len; i++) { - printf("%x ", decode->opcode[i]); - } - printf("\n"); - VM_PANIC("decoder failed\n"); -} - -uint64_t sign(uint64_t val, int size) -{ - switch (size) { - case 1: - val = (int8_t)val; - break; - case 2: - val = (int16_t)val; - break; - case 4: - val = (int32_t)val; - break; - case 8: - val = (int64_t)val; - break; - default: - VM_PANIC_EX("%s invalid size %d\n", __func__, size); - break; - } - return val; -} - -static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode, - int size) -{ - uint64_t val = 0; - - switch (size) { - case 1: - case 2: - case 4: - case 8: - break; - default: - VM_PANIC_EX("%s invalid size %d\n", __func__, size); - break; - } - target_ulong va = linear_rip(env_cpu(env), env->eip) + decode->len; - vmx_read_mem(env_cpu(env), &val, va, size); - decode->len += size; - - return val; -} - -static inline uint8_t decode_byte(CPUX86State *env, struct x86_decode *decode) -{ - return (uint8_t)decode_bytes(env, decode, 1); -} - -static inline uint16_t decode_word(CPUX86State *env, struct x86_decode *decode) -{ - return (uint16_t)decode_bytes(env, decode, 2); -} - -static inline uint32_t decode_dword(CPUX86State *env, struct x86_decode *decode) -{ - return (uint32_t)decode_bytes(env, decode, 4); -} - -static inline uint64_t decode_qword(CPUX86State *env, struct x86_decode *decode) -{ - return decode_bytes(env, decode, 8); -} - -static void decode_modrm_rm(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X86_VAR_RM; -} - -static void decode_modrm_reg(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X86_VAR_REG; - op->reg = decode->modrm.reg; - op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.r, - decode->operand_size); -} - -static void decode_rax(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X86_VAR_REG; - op->reg = R_EAX; - /* Since reg is always AX, REX prefix has no impact. */ - op->ptr = get_reg_ref(env, op->reg, false, 0, - decode->operand_size); -} - -static inline void decode_immediate(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *var, int size) -{ - var->type = X86_VAR_IMMEDIATE; - var->size = size; - switch (size) { - case 1: - var->val = decode_byte(env, decode); - break; - case 2: - var->val = decode_word(env, decode); - break; - case 4: - var->val = decode_dword(env, decode); - break; - case 8: - var->val = decode_qword(env, decode); - break; - default: - VM_PANIC_EX("bad size %d\n", size); - } -} - -static void decode_imm8(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - decode_immediate(env, decode, op, 1); - op->type = X86_VAR_IMMEDIATE; -} - -static void decode_imm8_signed(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - decode_immediate(env, decode, op, 1); - op->val = sign(op->val, 1); - op->type = X86_VAR_IMMEDIATE; -} - -static void decode_imm16(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - decode_immediate(env, decode, op, 2); - op->type = X86_VAR_IMMEDIATE; -} - - -static void decode_imm(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - if (8 == decode->operand_size) { - decode_immediate(env, decode, op, 4); - op->val = sign(op->val, decode->operand_size); - } else { - decode_immediate(env, decode, op, decode->operand_size); - } - op->type = X86_VAR_IMMEDIATE; -} - -static void decode_imm_signed(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - decode_immediate(env, decode, op, decode->operand_size); - op->val = sign(op->val, decode->operand_size); - op->type = X86_VAR_IMMEDIATE; -} - -static void decode_imm_1(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X86_VAR_IMMEDIATE; - op->val = 1; -} - -static void decode_imm_0(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X86_VAR_IMMEDIATE; - op->val = 0; -} - - -static void decode_pushseg(CPUX86State *env, struct x86_decode *decode) -{ - uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0]; - - decode->op[0].type = X86_VAR_REG; - switch (op) { - case 0xe: - decode->op[0].reg = R_CS; - break; - case 0x16: - decode->op[0].reg = R_SS; - break; - case 0x1e: - decode->op[0].reg = R_DS; - break; - case 0x06: - decode->op[0].reg = R_ES; - break; - case 0xa0: - decode->op[0].reg = R_FS; - break; - case 0xa8: - decode->op[0].reg = R_GS; - break; - } -} - -static void decode_popseg(CPUX86State *env, struct x86_decode *decode) -{ - uint8_t op = (decode->opcode_len > 1) ? decode->opcode[1] : decode->opcode[0]; - - decode->op[0].type = X86_VAR_REG; - switch (op) { - case 0xf: - decode->op[0].reg = R_CS; - break; - case 0x17: - decode->op[0].reg = R_SS; - break; - case 0x1f: - decode->op[0].reg = R_DS; - break; - case 0x07: - decode->op[0].reg = R_ES; - break; - case 0xa1: - decode->op[0].reg = R_FS; - break; - case 0xa9: - decode->op[0].reg = R_GS; - break; - } -} - -static void decode_incgroup(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = decode->opcode[0] - 0x40; - decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, - decode->rex.b, decode->operand_size); -} - -static void decode_decgroup(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = decode->opcode[0] - 0x48; - decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, - decode->rex.b, decode->operand_size); -} - -static void decode_incgroup2(CPUX86State *env, struct x86_decode *decode) -{ - if (!decode->modrm.reg) { - decode->cmd = X86_DECODE_CMD_INC; - } else if (1 == decode->modrm.reg) { - decode->cmd = X86_DECODE_CMD_DEC; - } -} - -static void decode_pushgroup(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = decode->opcode[0] - 0x50; - decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, - decode->rex.b, decode->operand_size); -} - -static void decode_popgroup(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = decode->opcode[0] - 0x58; - decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, - decode->rex.b, decode->operand_size); -} - -static void decode_jxx(CPUX86State *env, struct x86_decode *decode) -{ - decode->displacement = decode_bytes(env, decode, decode->operand_size); - decode->displacement_size = decode->operand_size; -} - -static void decode_farjmp(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_IMMEDIATE; - decode->op[0].val = decode_bytes(env, decode, decode->operand_size); - decode->displacement = decode_word(env, decode); -} - -static void decode_addgroup(CPUX86State *env, struct x86_decode *decode) -{ - enum x86_decode_cmd group[] = { - X86_DECODE_CMD_ADD, - X86_DECODE_CMD_OR, - X86_DECODE_CMD_ADC, - X86_DECODE_CMD_SBB, - X86_DECODE_CMD_AND, - X86_DECODE_CMD_SUB, - X86_DECODE_CMD_XOR, - X86_DECODE_CMD_CMP - }; - decode->cmd = group[decode->modrm.reg]; -} - -static void decode_rotgroup(CPUX86State *env, struct x86_decode *decode) -{ - enum x86_decode_cmd group[] = { - X86_DECODE_CMD_ROL, - X86_DECODE_CMD_ROR, - X86_DECODE_CMD_RCL, - X86_DECODE_CMD_RCR, - X86_DECODE_CMD_SHL, - X86_DECODE_CMD_SHR, - X86_DECODE_CMD_SHL, - X86_DECODE_CMD_SAR - }; - decode->cmd = group[decode->modrm.reg]; -} - -static void decode_f7group(CPUX86State *env, struct x86_decode *decode) -{ - enum x86_decode_cmd group[] = { - X86_DECODE_CMD_TST, - X86_DECODE_CMD_TST, - X86_DECODE_CMD_NOT, - X86_DECODE_CMD_NEG, - X86_DECODE_CMD_MUL, - X86_DECODE_CMD_IMUL_1, - X86_DECODE_CMD_DIV, - X86_DECODE_CMD_IDIV - }; - decode->cmd = group[decode->modrm.reg]; - decode_modrm_rm(env, decode, &decode->op[0]); - - switch (decode->modrm.reg) { - case 0: - case 1: - decode_imm(env, decode, &decode->op[1]); - break; - case 2: - break; - case 3: - decode->op[1].type = X86_VAR_IMMEDIATE; - decode->op[1].val = 0; - break; - default: - break; - } -} - -static void decode_xchgroup(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = decode->opcode[0] - 0x90; - decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, - decode->rex.b, decode->operand_size); -} - -static void decode_movgroup(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = decode->opcode[0] - 0xb8; - decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, - decode->rex.b, decode->operand_size); - decode_immediate(env, decode, &decode->op[1], decode->operand_size); -} - -static void fetch_moffs(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X86_VAR_OFFSET; - op->ptr = decode_bytes(env, decode, decode->addressing_size); -} - -static void decode_movgroup8(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = decode->opcode[0] - 0xb0; - decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, - decode->rex.b, decode->operand_size); - decode_immediate(env, decode, &decode->op[1], decode->operand_size); -} - -static void decode_rcx(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X86_VAR_REG; - op->reg = R_ECX; - op->ptr = get_reg_ref(env, op->reg, decode->rex.rex, decode->rex.b, - decode->operand_size); -} - -struct decode_tbl { - uint8_t opcode; - enum x86_decode_cmd cmd; - uint8_t operand_size; - bool is_modrm; - void (*decode_op1)(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op1); - void (*decode_op2)(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op2); - void (*decode_op3)(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op3); - void (*decode_op4)(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op4); - void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode); - uint32_t flags_mask; -}; - -struct decode_x87_tbl { - uint8_t opcode; - uint8_t modrm_reg; - uint8_t modrm_mod; - enum x86_decode_cmd cmd; - uint8_t operand_size; - bool rev; - bool pop; - void (*decode_op1)(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op1); - void (*decode_op2)(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op2); - void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode); - uint32_t flags_mask; -}; - -struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL, - decode_invalid}; - -struct decode_tbl _decode_tbl1[256]; -struct decode_tbl _decode_tbl2[256]; -struct decode_x87_tbl _decode_tbl3[256]; - -static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode) -{ - struct decode_x87_tbl *decoder; - - decode->is_fpu = true; - int mode = decode->modrm.mod == 3 ? 1 : 0; - int index = ((decode->opcode[0] & 0xf) << 4) | (mode << 3) | - decode->modrm.reg; - - decoder = &_decode_tbl3[index]; - - decode->cmd = decoder->cmd; - if (decoder->operand_size) { - decode->operand_size = decoder->operand_size; - } - decode->flags_mask = decoder->flags_mask; - decode->fpop_stack = decoder->pop; - decode->frev = decoder->rev; - - if (decoder->decode_op1) { - decoder->decode_op1(env, decode, &decode->op[0]); - } - if (decoder->decode_op2) { - decoder->decode_op2(env, decode, &decode->op[1]); - } - if (decoder->decode_postfix) { - decoder->decode_postfix(env, decode); - } - - VM_PANIC_ON_EX(!decode->cmd, "x87 opcode %x %x (%x %x) not decoded\n", - decode->opcode[0], decode->modrm.modrm, decoder->modrm_reg, - decoder->modrm_mod); -} - -static void decode_ffgroup(CPUX86State *env, struct x86_decode *decode) -{ - enum x86_decode_cmd group[] = { - X86_DECODE_CMD_INC, - X86_DECODE_CMD_DEC, - X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT, - X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT, - X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT, - X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT, - X86_DECODE_CMD_PUSH, - X86_DECODE_CMD_INVL, - X86_DECODE_CMD_INVL - }; - decode->cmd = group[decode->modrm.reg]; - if (decode->modrm.reg > 2) { - decode->flags_mask = 0; - } -} - -static void decode_sldtgroup(CPUX86State *env, struct x86_decode *decode) -{ - - enum x86_decode_cmd group[] = { - X86_DECODE_CMD_SLDT, - X86_DECODE_CMD_STR, - X86_DECODE_CMD_LLDT, - X86_DECODE_CMD_LTR, - X86_DECODE_CMD_VERR, - X86_DECODE_CMD_VERW, - X86_DECODE_CMD_INVL, - X86_DECODE_CMD_INVL - }; - decode->cmd = group[decode->modrm.reg]; -} - -static void decode_lidtgroup(CPUX86State *env, struct x86_decode *decode) -{ - enum x86_decode_cmd group[] = { - X86_DECODE_CMD_SGDT, - X86_DECODE_CMD_SIDT, - X86_DECODE_CMD_LGDT, - X86_DECODE_CMD_LIDT, - X86_DECODE_CMD_SMSW, - X86_DECODE_CMD_LMSW, - X86_DECODE_CMD_LMSW, - X86_DECODE_CMD_INVLPG - }; - decode->cmd = group[decode->modrm.reg]; - if (0xf9 == decode->modrm.modrm) { - decode->opcode[decode->len++] = decode->modrm.modrm; - decode->cmd = X86_DECODE_CMD_RDTSCP; - } -} - -static void decode_btgroup(CPUX86State *env, struct x86_decode *decode) -{ - enum x86_decode_cmd group[] = { - X86_DECODE_CMD_INVL, - X86_DECODE_CMD_INVL, - X86_DECODE_CMD_INVL, - X86_DECODE_CMD_INVL, - X86_DECODE_CMD_BT, - X86_DECODE_CMD_BTS, - X86_DECODE_CMD_BTR, - X86_DECODE_CMD_BTC - }; - decode->cmd = group[decode->modrm.reg]; -} - -static void decode_x87_general(CPUX86State *env, struct x86_decode *decode) -{ - decode->is_fpu = true; -} - -static void decode_x87_modrm_floatp(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X87_VAR_FLOATP; -} - -static void decode_x87_modrm_intp(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X87_VAR_INTP; -} - -static void decode_x87_modrm_bytep(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X87_VAR_BYTEP; -} - -static void decode_x87_modrm_st0(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X87_VAR_REG; - op->reg = 0; -} - -static void decode_decode_x87_modrm_st0(CPUX86State *env, - struct x86_decode *decode, - struct x86_decode_op *op) -{ - op->type = X87_VAR_REG; - op->reg = decode->modrm.modrm & 7; -} - - -static void decode_aegroup(CPUX86State *env, struct x86_decode *decode) -{ - decode->is_fpu = true; - switch (decode->modrm.reg) { - case 0: - decode->cmd = X86_DECODE_CMD_FXSAVE; - decode_x87_modrm_bytep(env, decode, &decode->op[0]); - break; - case 1: - decode_x87_modrm_bytep(env, decode, &decode->op[0]); - decode->cmd = X86_DECODE_CMD_FXRSTOR; - break; - case 5: - if (decode->modrm.modrm == 0xe8) { - decode->cmd = X86_DECODE_CMD_LFENCE; - } else { - VM_PANIC("xrstor"); - } - break; - case 6: - VM_PANIC_ON(decode->modrm.modrm != 0xf0); - decode->cmd = X86_DECODE_CMD_MFENCE; - break; - case 7: - if (decode->modrm.modrm == 0xf8) { - decode->cmd = X86_DECODE_CMD_SFENCE; - } else { - decode->cmd = X86_DECODE_CMD_CLFLUSH; - } - break; - default: - VM_PANIC_EX("0xae: reg %d\n", decode->modrm.reg); - break; - } -} - -static void decode_bswap(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = decode->opcode[1] - 0xc8; - decode->op[0].ptr = get_reg_ref(env, decode->op[0].reg, decode->rex.rex, - decode->rex.b, decode->operand_size); -} - -static void decode_d9_4(CPUX86State *env, struct x86_decode *decode) -{ - switch (decode->modrm.modrm) { - case 0xe0: - /* FCHS */ - decode->cmd = X86_DECODE_CMD_FCHS; - break; - case 0xe1: - decode->cmd = X86_DECODE_CMD_FABS; - break; - case 0xe4: - VM_PANIC("FTST"); - break; - case 0xe5: - /* FXAM */ - decode->cmd = X86_DECODE_CMD_FXAM; - break; - default: - VM_PANIC("FLDENV"); - break; - } -} - -static void decode_db_4(CPUX86State *env, struct x86_decode *decode) -{ - switch (decode->modrm.modrm) { - case 0xe0: - VM_PANIC_EX("unhandled FNENI: %x %x\n", decode->opcode[0], - decode->modrm.modrm); - break; - case 0xe1: - VM_PANIC_EX("unhandled FNDISI: %x %x\n", decode->opcode[0], - decode->modrm.modrm); - break; - case 0xe2: - VM_PANIC_EX("unhandled FCLEX: %x %x\n", decode->opcode[0], - decode->modrm.modrm); - break; - case 0xe3: - decode->cmd = X86_DECODE_CMD_FNINIT; - break; - case 0xe4: - decode->cmd = X86_DECODE_CMD_FNSETPM; - break; - default: - VM_PANIC_EX("unhandled fpu opcode: %x %x\n", decode->opcode[0], - decode->modrm.modrm); - break; - } -} - - -#define RFLAGS_MASK_NONE 0 -#define RFLAGS_MASK_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C) -#define RFLAGS_MASK_LAHF (CC_S | CC_Z | CC_A | CC_P | CC_C) -#define RFLAGS_MASK_CF (CC_C) -#define RFLAGS_MASK_IF (IF_MASK) -#define RFLAGS_MASK_TF (TF_MASK) -#define RFLAGS_MASK_DF (DF_MASK) -#define RFLAGS_MASK_ZF (CC_Z) - -struct decode_tbl _1op_inst[] = { - {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL, - NULL, RFLAGS_MASK_OSZAPC}, - {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL, - NULL, RFLAGS_MASK_OSZAPC}, - {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL, - decode_pushseg, RFLAGS_MASK_NONE}, - {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL, - decode_popseg, RFLAGS_MASK_NONE}, - {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, - {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, - - {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, - {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, - - {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, - {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, - - {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x2f, X86_DECODE_CMD_DAS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0x3f, X86_DECODE_CMD_AAS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0x40, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, - {0x41, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, - {0x42, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, - {0x43, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, - {0x44, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, - {0x45, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, - {0x46, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, - {0x47, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, - - {0x48, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, - {0x49, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, - {0x4a, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, - {0x4b, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, - {0x4c, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, - {0x4d, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, - {0x4e, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, - {0x4f, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, - - {0x50, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, - {0x51, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, - {0x52, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, - {0x53, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, - {0x54, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, - {0x55, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, - {0x56, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, - {0x57, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, - - {0x58, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, - {0x59, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, - {0x5a, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, - {0x5b, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, - {0x5c, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, - {0x5d, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, - {0x5e, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, - {0x5f, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, - - {0x60, X86_DECODE_CMD_PUSHA, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x61, X86_DECODE_CMD_POPA, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, - decode_modrm_rm, decode_imm, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm, - decode_imm8_signed, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0x6c, X86_DECODE_CMD_INS, 1, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x6d, X86_DECODE_CMD_INS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x6e, X86_DECODE_CMD_OUTS, 1, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x6f, X86_DECODE_CMD_OUTS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0x70, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x71, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x72, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x73, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x74, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x75, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x76, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x77, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x78, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x79, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x7a, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x7b, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x7c, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x7d, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x7e, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x7f, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - - {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, - {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm, - NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, - {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, - {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed, - NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, - {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm, - decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg, - decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0x90, X86_DECODE_CMD_NOP, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, - {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, - {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, - {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, - {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, - {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, - {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, - - {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL, - NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE}, - - {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_POPF},*/ - {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_LAHF}, - - {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, - {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, - {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, - {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, - {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, - {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, - {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, - {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, - - {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, - {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, - {0xba, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, - {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, - {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, - {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, - {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, - {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, - - {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, - {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, - - {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_IRET},*/ - - {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, - {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, - {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, - {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, - - {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0xd7, X86_DECODE_CMD_XLAT, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, - {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, - {0xda, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, - {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, - {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, - {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, - {0xde, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, - {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, - - {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xe3, X86_DECODE_CMD_JCXZ, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - - {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xea, X86_DECODE_CMD_JMP_FAR, 0, false, - NULL, NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE}, - {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xec, X86_DECODE_CMD_IN, 1, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xed, X86_DECODE_CMD_IN, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xee, X86_DECODE_CMD_OUT, 1, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xef, X86_DECODE_CMD_OUT, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xf4, X86_DECODE_CMD_HLT, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xf5, X86_DECODE_CMD_CMC, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, - - {0xf6, X86_DECODE_CMD_INVL, 1, true, - NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC}, - {0xf7, X86_DECODE_CMD_INVL, 0, true, - NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC}, - - {0xf8, X86_DECODE_CMD_CLC, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, - {0xf9, X86_DECODE_CMD_STC, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, - - {0xfa, X86_DECODE_CMD_CLI, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF}, - {0xfb, X86_DECODE_CMD_STI, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF}, - {0xfc, X86_DECODE_CMD_CLD, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF}, - {0xfd, X86_DECODE_CMD_STD, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF}, - {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, - NULL, NULL, NULL, decode_incgroup2, RFLAGS_MASK_OSZAPC}, - {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, - NULL, NULL, NULL, decode_ffgroup, RFLAGS_MASK_OSZAPC}, -}; - -struct decode_tbl _2op_inst[] = { - {0x0, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, - NULL, NULL, NULL, decode_sldtgroup, RFLAGS_MASK_NONE}, - {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, - NULL, NULL, NULL, decode_lidtgroup, RFLAGS_MASK_NONE}, - {0x6, X86_DECODE_CMD_CLTS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_TF}, - {0x9, X86_DECODE_CMD_WBINVD, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x18, X86_DECODE_CMD_PREFETCH, 0, true, - NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE}, - {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm, - decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm, - decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg, - decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg, - decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x30, X86_DECODE_CMD_WRMSR, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x31, X86_DECODE_CMD_RDTSC, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x32, X86_DECODE_CMD_RDMSR, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x77, X86_DECODE_CMD_EMMS, 0, false, - NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE}, - {0x82, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x83, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x84, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x85, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x86, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x87, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x88, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x89, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x8a, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x8b, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x8c, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x8d, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x8e, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x8f, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, - {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, - {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, - {0xa2, X86_DECODE_CMD_CPUID, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_CF}, - {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg, - decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg, - decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, - {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, - {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_CF}, - {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg, - decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg, - decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, - NULL, NULL, NULL, decode_aegroup, RFLAGS_MASK_NONE}, - - {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, - {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_btgroup, RFLAGS_MASK_OSZAPC}, - {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, - - {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_ZF}, - - {0xc8, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, - {0xc9, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, - {0xca, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, - {0xcb, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, - {0xcc, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, - {0xcd, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, - {0xce, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, - {0xcf, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, -}; - -struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL, - NULL, decode_invalid, 0}; - -struct decode_x87_tbl _x87_inst[] = { - {0xd8, 0, 3, X86_DECODE_CMD_FADD, 10, false, false, - decode_x87_modrm_st0, decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xd8, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0, - decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - - {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, - decode_x87_modrm_st0, NULL, decode_d9_4, RFLAGS_MASK_NONE}, - {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 5, 3, X86_DECODE_CMD_FLDxx, 10, false, false, NULL, NULL, NULL, - RFLAGS_MASK_NONE}, - {0xd9, 5, 0, X86_DECODE_CMD_FLDCW, 2, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, - {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, - decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xda, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, - RFLAGS_MASK_NONE}, - {0xda, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0, - decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xda, 6, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, - RFLAGS_MASK_NONE}, - {0xda, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xda, 7, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, - RFLAGS_MASK_NONE}, - {0xda, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - - {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, - decode_db_4, RFLAGS_MASK_NONE}, - {0xdb, 4, 0, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, NULL, - RFLAGS_MASK_NONE}, - {0xdb, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, - - {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, - - {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, - - {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, - {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, - {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, -}; - -void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - target_ulong ptr = 0; - X86Seg seg = R_DS; - - if (!decode->modrm.mod && 6 == decode->modrm.rm) { - ptr = decode->displacement; - goto calc_addr; - } - - if (decode->displacement_size) { - ptr = sign(decode->displacement, decode->displacement_size); - } - - switch (decode->modrm.rm) { - case 0: - ptr += BX(env) + SI(env); - break; - case 1: - ptr += BX(env) + DI(env); - break; - case 2: - ptr += BP(env) + SI(env); - seg = R_SS; - break; - case 3: - ptr += BP(env) + DI(env); - seg = R_SS; - break; - case 4: - ptr += SI(env); - break; - case 5: - ptr += DI(env); - break; - case 6: - ptr += BP(env); - seg = R_SS; - break; - case 7: - ptr += BX(env); - break; - } -calc_addr: - if (X86_DECODE_CMD_LEA == decode->cmd) { - op->ptr = (uint16_t)ptr; - } else { - op->ptr = decode_linear_addr(env, decode, (uint16_t)ptr, seg); - } -} - -target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present, - int is_extended, int size) -{ - target_ulong ptr = 0; - - if (is_extended) { - reg |= R_R8; - } - - switch (size) { - case 1: - if (is_extended || reg < 4 || rex_present) { - ptr = (target_ulong)&RL(env, reg); - } else { - ptr = (target_ulong)&RH(env, reg - 4); - } - break; - default: - ptr = (target_ulong)&RRX(env, reg); - break; - } - return ptr; -} - -target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present, - int is_extended, int size) -{ - target_ulong val = 0; - memcpy(&val, - (void *)get_reg_ref(env, reg, rex_present, is_extended, size), - size); - return val; -} - -static target_ulong get_sib_val(CPUX86State *env, struct x86_decode *decode, - X86Seg *sel) -{ - target_ulong base = 0; - target_ulong scaled_index = 0; - int addr_size = decode->addressing_size; - int base_reg = decode->sib.base; - int index_reg = decode->sib.index; - - *sel = R_DS; - - if (decode->modrm.mod || base_reg != R_EBP) { - if (decode->rex.b) { - base_reg |= R_R8; - } - if (base_reg == R_ESP || base_reg == R_EBP) { - *sel = R_SS; - } - base = get_reg_val(env, decode->sib.base, decode->rex.rex, - decode->rex.b, addr_size); - } - - if (decode->rex.x) { - index_reg |= R_R8; - } - - if (index_reg != R_ESP) { - scaled_index = get_reg_val(env, index_reg, decode->rex.rex, - decode->rex.x, addr_size) << - decode->sib.scale; - } - return base + scaled_index; -} - -void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - X86Seg seg = R_DS; - target_ulong ptr = 0; - int addr_size = decode->addressing_size; - - if (decode->displacement_size) { - ptr = sign(decode->displacement, decode->displacement_size); - } - - if (4 == decode->modrm.rm) { - ptr += get_sib_val(env, decode, &seg); - } else if (!decode->modrm.mod && 5 == decode->modrm.rm) { - if (x86_is_long_mode(env_cpu(env))) { - ptr += env->eip + decode->len; - } else { - ptr = decode->displacement; - } - } else { - if (decode->modrm.rm == R_EBP || decode->modrm.rm == R_ESP) { - seg = R_SS; - } - ptr += get_reg_val(env, decode->modrm.rm, decode->rex.rex, - decode->rex.b, addr_size); - } - - if (X86_DECODE_CMD_LEA == decode->cmd) { - op->ptr = (uint32_t)ptr; - } else { - op->ptr = decode_linear_addr(env, decode, (uint32_t)ptr, seg); - } -} - -void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - X86Seg seg = R_DS; - int32_t offset = 0; - int mod = decode->modrm.mod; - int rm = decode->modrm.rm; - target_ulong ptr; - int src = decode->modrm.rm; - - if (decode->displacement_size) { - offset = sign(decode->displacement, decode->displacement_size); - } - - if (4 == rm) { - ptr = get_sib_val(env, decode, &seg) + offset; - } else if (0 == mod && 5 == rm) { - ptr = env->eip + decode->len + (int32_t) offset; - } else { - ptr = get_reg_val(env, src, decode->rex.rex, decode->rex.b, 8) + - (int64_t) offset; - } - - if (X86_DECODE_CMD_LEA == decode->cmd) { - op->ptr = ptr; - } else { - op->ptr = decode_linear_addr(env, decode, ptr, seg); - } -} - - -void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op) -{ - if (3 == decode->modrm.mod) { - op->reg = decode->modrm.reg; - op->type = X86_VAR_REG; - op->ptr = get_reg_ref(env, decode->modrm.rm, decode->rex.rex, - decode->rex.b, decode->operand_size); - return; - } - - switch (decode->addressing_size) { - case 2: - calc_modrm_operand16(env, decode, op); - break; - case 4: - calc_modrm_operand32(env, decode, op); - break; - case 8: - calc_modrm_operand64(env, decode, op); - break; - default: - VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size); - break; - } -} - -static void decode_prefix(CPUX86State *env, struct x86_decode *decode) -{ - while (1) { - /* - * REX prefix must come after legacy prefixes. - * REX before legacy is ignored. - * Clear rex to simulate this. - */ - uint8_t byte = decode_byte(env, decode); - switch (byte) { - case PREFIX_LOCK: - decode->lock = byte; - decode->rex.rex = 0; - break; - case PREFIX_REPN: - case PREFIX_REP: - decode->rep = byte; - decode->rex.rex = 0; - break; - case PREFIX_CS_SEG_OVERRIDE: - case PREFIX_SS_SEG_OVERRIDE: - case PREFIX_DS_SEG_OVERRIDE: - case PREFIX_ES_SEG_OVERRIDE: - case PREFIX_FS_SEG_OVERRIDE: - case PREFIX_GS_SEG_OVERRIDE: - decode->segment_override = byte; - decode->rex.rex = 0; - break; - case PREFIX_OP_SIZE_OVERRIDE: - decode->op_size_override = byte; - decode->rex.rex = 0; - break; - case PREFIX_ADDR_SIZE_OVERRIDE: - decode->addr_size_override = byte; - decode->rex.rex = 0; - break; - case PREFIX_REX ... (PREFIX_REX + 0xf): - if (x86_is_long_mode(env_cpu(env))) { - decode->rex.rex = byte; - break; - } - /* fall through when not in long mode */ - default: - decode->len--; - return; - } - } -} - -static struct x86_segment_descriptor get_cs_descriptor(CPUState *s) -{ - struct vmx_segment vmx_cs; - x86_segment_descriptor cs; - vmx_read_segment_descriptor(s, &vmx_cs, R_CS); - vmx_segment_to_x86_descriptor(s, &vmx_cs, &cs); - - return cs; -} - -void set_addressing_size(CPUX86State *env, struct x86_decode *decode) -{ - decode->addressing_size = -1; - if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) { - if (decode->addr_size_override) { - decode->addressing_size = 4; - } else { - decode->addressing_size = 2; - } - } else if (!x86_is_long_mode(env_cpu(env))) { - /* protected */ - x86_segment_descriptor cs = get_cs_descriptor(env_cpu(env)); - /* check db */ - if (cs.db) { - if (decode->addr_size_override) { - decode->addressing_size = 2; - } else { - decode->addressing_size = 4; - } - } else { - if (decode->addr_size_override) { - decode->addressing_size = 4; - } else { - decode->addressing_size = 2; - } - } - } else { - /* long */ - if (decode->addr_size_override) { - decode->addressing_size = 4; - } else { - decode->addressing_size = 8; - } - } -} - -void set_operand_size(CPUX86State *env, struct x86_decode *decode) -{ - decode->operand_size = -1; - if (x86_is_real(env_cpu(env)) || x86_is_v8086(env_cpu(env))) { - if (decode->op_size_override) { - decode->operand_size = 4; - } else { - decode->operand_size = 2; - } - } else if (!x86_is_long_mode(env_cpu(env))) { - /* protected */ - x86_segment_descriptor cs = get_cs_descriptor(env_cpu(env)); - /* check db */ - if (cs.db) { - if (decode->op_size_override) { - decode->operand_size = 2; - } else{ - decode->operand_size = 4; - } - } else { - if (decode->op_size_override) { - decode->operand_size = 4; - } else { - decode->operand_size = 2; - } - } - } else { - /* long */ - if (decode->op_size_override) { - decode->operand_size = 2; - } else { - decode->operand_size = 4; - } - - if (decode->rex.w) { - decode->operand_size = 8; - } - } -} - -static void decode_sib(CPUX86State *env, struct x86_decode *decode) -{ - if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) && - (decode->addressing_size != 2)) { - decode->sib.sib = decode_byte(env, decode); - decode->sib_present = true; - } -} - -/* 16 bit modrm */ -int disp16_tbl[4][8] = { - {0, 0, 0, 0, 0, 0, 2, 0}, - {1, 1, 1, 1, 1, 1, 1, 1}, - {2, 2, 2, 2, 2, 2, 2, 2}, - {0, 0, 0, 0, 0, 0, 0, 0} -}; - -/* 32/64-bit modrm */ -int disp32_tbl[4][8] = { - {0, 0, 0, 0, -1, 4, 0, 0}, - {1, 1, 1, 1, 1, 1, 1, 1}, - {4, 4, 4, 4, 4, 4, 4, 4}, - {0, 0, 0, 0, 0, 0, 0, 0} -}; - -static inline void decode_displacement(CPUX86State *env, struct x86_decode *decode) -{ - int addressing_size = decode->addressing_size; - int mod = decode->modrm.mod; - int rm = decode->modrm.rm; - - decode->displacement_size = 0; - switch (addressing_size) { - case 2: - decode->displacement_size = disp16_tbl[mod][rm]; - if (decode->displacement_size) { - decode->displacement = (uint16_t)decode_bytes(env, decode, - decode->displacement_size); - } - break; - case 4: - case 8: - if (-1 == disp32_tbl[mod][rm]) { - if (5 == decode->sib.base) { - decode->displacement_size = 4; - } - } else { - decode->displacement_size = disp32_tbl[mod][rm]; - } - - if (decode->displacement_size) { - decode->displacement = (uint32_t)decode_bytes(env, decode, - decode->displacement_size); - } - break; - } -} - -static inline void decode_modrm(CPUX86State *env, struct x86_decode *decode) -{ - decode->modrm.modrm = decode_byte(env, decode); - decode->is_modrm = true; - - decode_sib(env, decode); - decode_displacement(env, decode); -} - -static inline void decode_opcode_general(CPUX86State *env, - struct x86_decode *decode, - uint8_t opcode, - struct decode_tbl *inst_decoder) -{ - decode->cmd = inst_decoder->cmd; - if (inst_decoder->operand_size) { - decode->operand_size = inst_decoder->operand_size; - } - decode->flags_mask = inst_decoder->flags_mask; - - if (inst_decoder->is_modrm) { - decode_modrm(env, decode); - } - if (inst_decoder->decode_op1) { - inst_decoder->decode_op1(env, decode, &decode->op[0]); - } - if (inst_decoder->decode_op2) { - inst_decoder->decode_op2(env, decode, &decode->op[1]); - } - if (inst_decoder->decode_op3) { - inst_decoder->decode_op3(env, decode, &decode->op[2]); - } - if (inst_decoder->decode_op4) { - inst_decoder->decode_op4(env, decode, &decode->op[3]); - } - if (inst_decoder->decode_postfix) { - inst_decoder->decode_postfix(env, decode); - } -} - -static inline void decode_opcode_1(CPUX86State *env, struct x86_decode *decode, - uint8_t opcode) -{ - struct decode_tbl *inst_decoder = &_decode_tbl1[opcode]; - decode_opcode_general(env, decode, opcode, inst_decoder); -} - - -static inline void decode_opcode_2(CPUX86State *env, struct x86_decode *decode, - uint8_t opcode) -{ - struct decode_tbl *inst_decoder = &_decode_tbl2[opcode]; - decode_opcode_general(env, decode, opcode, inst_decoder); -} - -static void decode_opcodes(CPUX86State *env, struct x86_decode *decode) -{ - uint8_t opcode; - - opcode = decode_byte(env, decode); - decode->opcode[decode->opcode_len++] = opcode; - if (opcode != OPCODE_ESCAPE) { - decode_opcode_1(env, decode, opcode); - } else { - opcode = decode_byte(env, decode); - decode->opcode[decode->opcode_len++] = opcode; - decode_opcode_2(env, decode, opcode); - } -} - -uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode) -{ - memset(decode, 0, sizeof(*decode)); - decode_prefix(env, decode); - set_addressing_size(env, decode); - set_operand_size(env, decode); - - decode_opcodes(env, decode); - - return decode->len; -} - -void init_decoder(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(_decode_tbl1); i++) { - memcpy(&_decode_tbl1[i], &invl_inst, sizeof(invl_inst)); - } - for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) { - memcpy(&_decode_tbl2[i], &invl_inst, sizeof(invl_inst)); - } - for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) { - memcpy(&_decode_tbl3[i], &invl_inst_x87, sizeof(invl_inst_x87)); - - } - for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) { - _decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i]; - } - for (i = 0; i < ARRAY_SIZE(_2op_inst); i++) { - _decode_tbl2[_2op_inst[i].opcode] = _2op_inst[i]; - } - for (i = 0; i < ARRAY_SIZE(_x87_inst); i++) { - int index = ((_x87_inst[i].opcode & 0xf) << 4) | - ((_x87_inst[i].modrm_mod & 1) << 3) | - _x87_inst[i].modrm_reg; - _decode_tbl3[index] = _x87_inst[i]; - } -} - - -const char *decode_cmd_to_string(enum x86_decode_cmd cmd) -{ - static const char *cmds[] = {"INVL", "PUSH", "PUSH_SEG", "POP", "POP_SEG", - "MOV", "MOVSX", "MOVZX", "CALL_NEAR", "CALL_NEAR_ABS_INDIRECT", - "CALL_FAR_ABS_INDIRECT", "CMD_CALL_FAR", "RET_NEAR", "RET_FAR", "ADD", - "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP", "INC", "DEC", "TST", - "NOT", "NEG", "JMP_NEAR", "JMP_NEAR_ABS_INDIRECT", "JMP_FAR", - "JMP_FAR_ABS_INDIRECT", "LEA", "JXX", "JCXZ", "SETXX", "MOV_TO_SEG", - "MOV_FROM_SEG", "CLI", "STI", "CLD", "STD", "STC", "CLC", "OUT", "IN", - "INS", "OUTS", "LIDT", "SIDT", "LGDT", "SGDT", "SMSW", "LMSW", - "RDTSCP", "INVLPG", "MOV_TO_CR", "MOV_FROM_CR", "MOV_TO_DR", - "MOV_FROM_DR", "PUSHF", "POPF", "CPUID", "ROL", "ROR", "RCL", "RCR", - "SHL", "SAL", "SHR", "SHRD", "SHLD", "SAR", "DIV", "IDIV", "MUL", - "IMUL_3", "IMUL_2", "IMUL_1", "MOVS", "CMPS", "SCAS", "LODS", "STOS", - "BSWAP", "XCHG", "RDTSC", "RDMSR", "WRMSR", "ENTER", "LEAVE", "BT", - "BTS", "BTC", "BTR", "BSF", "BSR", "IRET", "INT", "POPA", "PUSHA", - "CWD", "CBW", "DAS", "AAD", "AAM", "AAS", "LOOP", "SLDT", "STR", "LLDT", - "LTR", "VERR", "VERW", "SAHF", "LAHF", "WBINVD", "LDS", "LSS", "LES", - "LGS", "LFS", "CMC", "XLAT", "NOP", "CMOV", "CLTS", "XADD", "HLT", - "CMPXCHG8B", "CMPXCHG", "POPCNT", "FNINIT", "FLD", "FLDxx", "FNSTCW", - "FNSTSW", "FNSETPM", "FSAVE", "FRSTOR", "FXSAVE", "FXRSTOR", "FDIV", - "FMUL", "FSUB", "FADD", "EMMS", "MFENCE", "SFENCE", "LFENCE", - "PREFETCH", "FST", "FABS", "FUCOM", "FUCOMI", "FLDCW", - "FXCH", "FCHS", "FCMOV", "FRNDINT", "FXAM", "LAST"}; - return cmds[cmd]; -} - -target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode, - target_ulong addr, X86Seg seg) -{ - switch (decode->segment_override) { - case PREFIX_CS_SEG_OVERRIDE: - seg = R_CS; - break; - case PREFIX_SS_SEG_OVERRIDE: - seg = R_SS; - break; - case PREFIX_DS_SEG_OVERRIDE: - seg = R_DS; - break; - case PREFIX_ES_SEG_OVERRIDE: - seg = R_ES; - break; - case PREFIX_FS_SEG_OVERRIDE: - seg = R_FS; - break; - case PREFIX_GS_SEG_OVERRIDE: - seg = R_GS; - break; - default: - break; - } - return linear_addr_size(env_cpu(env), addr, decode->addressing_size, seg); -} diff --git a/target/i386/hvf/x86_decode.h b/target/i386/hvf/x86_decode.h deleted file mode 100644 index a2d7a2a27b..0000000000 --- a/target/i386/hvf/x86_decode.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) 2016 Veertu Inc, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef HVF_X86_DECODE_H -#define HVF_X86_DECODE_H - -#include "cpu.h" -#include "x86.h" - -typedef enum x86_prefix { - /* group 1 */ - PREFIX_LOCK = 0xf0, - PREFIX_REPN = 0xf2, - PREFIX_REP = 0xf3, - /* group 2 */ - PREFIX_CS_SEG_OVERRIDE = 0x2e, - PREFIX_SS_SEG_OVERRIDE = 0x36, - PREFIX_DS_SEG_OVERRIDE = 0x3e, - PREFIX_ES_SEG_OVERRIDE = 0x26, - PREFIX_FS_SEG_OVERRIDE = 0x64, - PREFIX_GS_SEG_OVERRIDE = 0x65, - /* group 3 */ - PREFIX_OP_SIZE_OVERRIDE = 0x66, - /* group 4 */ - PREFIX_ADDR_SIZE_OVERRIDE = 0x67, - - PREFIX_REX = 0x40, -} x86_prefix; - -enum x86_decode_cmd { - X86_DECODE_CMD_INVL = 0, - - X86_DECODE_CMD_PUSH, - X86_DECODE_CMD_PUSH_SEG, - X86_DECODE_CMD_POP, - X86_DECODE_CMD_POP_SEG, - X86_DECODE_CMD_MOV, - X86_DECODE_CMD_MOVSX, - X86_DECODE_CMD_MOVZX, - X86_DECODE_CMD_CALL_NEAR, - X86_DECODE_CMD_CALL_NEAR_ABS_INDIRECT, - X86_DECODE_CMD_CALL_FAR_ABS_INDIRECT, - X86_DECODE_CMD_CALL_FAR, - X86_DECODE_RET_NEAR, - X86_DECODE_RET_FAR, - X86_DECODE_CMD_ADD, - X86_DECODE_CMD_OR, - X86_DECODE_CMD_ADC, - X86_DECODE_CMD_SBB, - X86_DECODE_CMD_AND, - X86_DECODE_CMD_SUB, - X86_DECODE_CMD_XOR, - X86_DECODE_CMD_CMP, - X86_DECODE_CMD_INC, - X86_DECODE_CMD_DEC, - X86_DECODE_CMD_TST, - X86_DECODE_CMD_NOT, - X86_DECODE_CMD_NEG, - X86_DECODE_CMD_JMP_NEAR, - X86_DECODE_CMD_JMP_NEAR_ABS_INDIRECT, - X86_DECODE_CMD_JMP_FAR, - X86_DECODE_CMD_JMP_FAR_ABS_INDIRECT, - X86_DECODE_CMD_LEA, - X86_DECODE_CMD_JXX, - X86_DECODE_CMD_JCXZ, - X86_DECODE_CMD_SETXX, - X86_DECODE_CMD_MOV_TO_SEG, - X86_DECODE_CMD_MOV_FROM_SEG, - X86_DECODE_CMD_CLI, - X86_DECODE_CMD_STI, - X86_DECODE_CMD_CLD, - X86_DECODE_CMD_STD, - X86_DECODE_CMD_STC, - X86_DECODE_CMD_CLC, - X86_DECODE_CMD_OUT, - X86_DECODE_CMD_IN, - X86_DECODE_CMD_INS, - X86_DECODE_CMD_OUTS, - X86_DECODE_CMD_LIDT, - X86_DECODE_CMD_SIDT, - X86_DECODE_CMD_LGDT, - X86_DECODE_CMD_SGDT, - X86_DECODE_CMD_SMSW, - X86_DECODE_CMD_LMSW, - X86_DECODE_CMD_RDTSCP, - X86_DECODE_CMD_INVLPG, - X86_DECODE_CMD_MOV_TO_CR, - X86_DECODE_CMD_MOV_FROM_CR, - X86_DECODE_CMD_MOV_TO_DR, - X86_DECODE_CMD_MOV_FROM_DR, - X86_DECODE_CMD_PUSHF, - X86_DECODE_CMD_POPF, - X86_DECODE_CMD_CPUID, - X86_DECODE_CMD_ROL, - X86_DECODE_CMD_ROR, - X86_DECODE_CMD_RCL, - X86_DECODE_CMD_RCR, - X86_DECODE_CMD_SHL, - X86_DECODE_CMD_SAL, - X86_DECODE_CMD_SHR, - X86_DECODE_CMD_SHRD, - X86_DECODE_CMD_SHLD, - X86_DECODE_CMD_SAR, - X86_DECODE_CMD_DIV, - X86_DECODE_CMD_IDIV, - X86_DECODE_CMD_MUL, - X86_DECODE_CMD_IMUL_3, - X86_DECODE_CMD_IMUL_2, - X86_DECODE_CMD_IMUL_1, - X86_DECODE_CMD_MOVS, - X86_DECODE_CMD_CMPS, - X86_DECODE_CMD_SCAS, - X86_DECODE_CMD_LODS, - X86_DECODE_CMD_STOS, - X86_DECODE_CMD_BSWAP, - X86_DECODE_CMD_XCHG, - X86_DECODE_CMD_RDTSC, - X86_DECODE_CMD_RDMSR, - X86_DECODE_CMD_WRMSR, - X86_DECODE_CMD_ENTER, - X86_DECODE_CMD_LEAVE, - X86_DECODE_CMD_BT, - X86_DECODE_CMD_BTS, - X86_DECODE_CMD_BTC, - X86_DECODE_CMD_BTR, - X86_DECODE_CMD_BSF, - X86_DECODE_CMD_BSR, - X86_DECODE_CMD_IRET, - X86_DECODE_CMD_INT, - X86_DECODE_CMD_POPA, - X86_DECODE_CMD_PUSHA, - X86_DECODE_CMD_CWD, - X86_DECODE_CMD_CBW, - X86_DECODE_CMD_DAS, - X86_DECODE_CMD_AAD, - X86_DECODE_CMD_AAM, - X86_DECODE_CMD_AAS, - X86_DECODE_CMD_LOOP, - X86_DECODE_CMD_SLDT, - X86_DECODE_CMD_STR, - X86_DECODE_CMD_LLDT, - X86_DECODE_CMD_LTR, - X86_DECODE_CMD_VERR, - X86_DECODE_CMD_VERW, - X86_DECODE_CMD_SAHF, - X86_DECODE_CMD_LAHF, - X86_DECODE_CMD_WBINVD, - X86_DECODE_CMD_LDS, - X86_DECODE_CMD_LSS, - X86_DECODE_CMD_LES, - X86_DECODE_XMD_LGS, - X86_DECODE_CMD_LFS, - X86_DECODE_CMD_CMC, - X86_DECODE_CMD_XLAT, - X86_DECODE_CMD_NOP, - X86_DECODE_CMD_CMOV, - X86_DECODE_CMD_CLTS, - X86_DECODE_CMD_XADD, - X86_DECODE_CMD_HLT, - X86_DECODE_CMD_CMPXCHG8B, - X86_DECODE_CMD_CMPXCHG, - X86_DECODE_CMD_POPCNT, - - X86_DECODE_CMD_FNINIT, - X86_DECODE_CMD_FLD, - X86_DECODE_CMD_FLDxx, - X86_DECODE_CMD_FNSTCW, - X86_DECODE_CMD_FNSTSW, - X86_DECODE_CMD_FNSETPM, - X86_DECODE_CMD_FSAVE, - X86_DECODE_CMD_FRSTOR, - X86_DECODE_CMD_FXSAVE, - X86_DECODE_CMD_FXRSTOR, - X86_DECODE_CMD_FDIV, - X86_DECODE_CMD_FMUL, - X86_DECODE_CMD_FSUB, - X86_DECODE_CMD_FADD, - X86_DECODE_CMD_EMMS, - X86_DECODE_CMD_MFENCE, - X86_DECODE_CMD_SFENCE, - X86_DECODE_CMD_LFENCE, - X86_DECODE_CMD_PREFETCH, - X86_DECODE_CMD_CLFLUSH, - X86_DECODE_CMD_FST, - X86_DECODE_CMD_FABS, - X86_DECODE_CMD_FUCOM, - X86_DECODE_CMD_FUCOMI, - X86_DECODE_CMD_FLDCW, - X86_DECODE_CMD_FXCH, - X86_DECODE_CMD_FCHS, - X86_DECODE_CMD_FCMOV, - X86_DECODE_CMD_FRNDINT, - X86_DECODE_CMD_FXAM, - - X86_DECODE_CMD_LAST, -}; - -const char *decode_cmd_to_string(enum x86_decode_cmd cmd); - -typedef struct x86_modrm { - union { - uint8_t modrm; - struct { - uint8_t rm:3; - uint8_t reg:3; - uint8_t mod:2; - }; - }; -} __attribute__ ((__packed__)) x86_modrm; - -typedef struct x86_sib { - union { - uint8_t sib; - struct { - uint8_t base:3; - uint8_t index:3; - uint8_t scale:2; - }; - }; -} __attribute__ ((__packed__)) x86_sib; - -typedef struct x86_rex { - union { - uint8_t rex; - struct { - uint8_t b:1; - uint8_t x:1; - uint8_t r:1; - uint8_t w:1; - uint8_t unused:4; - }; - }; -} __attribute__ ((__packed__)) x86_rex; - -typedef enum x86_var_type { - X86_VAR_IMMEDIATE, - X86_VAR_OFFSET, - X86_VAR_REG, - X86_VAR_RM, - - /* for floating point computations */ - X87_VAR_REG, - X87_VAR_FLOATP, - X87_VAR_INTP, - X87_VAR_BYTEP, -} x86_var_type; - -typedef struct x86_decode_op { - enum x86_var_type type; - int size; - - int reg; - target_ulong val; - - target_ulong ptr; -} x86_decode_op; - -typedef struct x86_decode { - int len; - uint8_t opcode[4]; - uint8_t opcode_len; - enum x86_decode_cmd cmd; - int addressing_size; - int operand_size; - int lock; - int rep; - int op_size_override; - int addr_size_override; - int segment_override; - int control_change_inst; - bool fwait; - bool fpop_stack; - bool frev; - - uint32_t displacement; - uint8_t displacement_size; - struct x86_rex rex; - bool is_modrm; - bool sib_present; - struct x86_sib sib; - struct x86_modrm modrm; - struct x86_decode_op op[4]; - bool is_fpu; - uint32_t flags_mask; - -} x86_decode; - -uint64_t sign(uint64_t val, int size); - -uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode); - -target_ulong get_reg_ref(CPUX86State *env, int reg, int rex_present, - int is_extended, int size); -target_ulong get_reg_val(CPUX86State *env, int reg, int rex_present, - int is_extended, int size); -void calc_modrm_operand(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op); -target_ulong decode_linear_addr(CPUX86State *env, struct x86_decode *decode, - target_ulong addr, enum X86Seg seg); - -void init_decoder(void); -void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op); -void calc_modrm_operand32(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op); -void calc_modrm_operand64(CPUX86State *env, struct x86_decode *decode, - struct x86_decode_op *op); -void set_addressing_size(CPUX86State *env, struct x86_decode *decode); -void set_operand_size(CPUX86State *env, struct x86_decode *decode); - -#endif diff --git a/target/i386/hvf/x86_descr.h b/target/i386/hvf/x86_descr.h index ce5de98349..24af4946cd 100644 --- a/target/i386/hvf/x86_descr.h +++ b/target/i386/hvf/x86_descr.h @@ -19,7 +19,7 @@ #ifndef HVF_X86_DESCR_H #define HVF_X86_DESCR_H -#include "x86.h" +#include "emulate/x86.h" typedef struct vmx_segment { uint16_t sel; diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c deleted file mode 100644 index ebba80a36b..0000000000 --- a/target/i386/hvf/x86_emu.c +++ /dev/null @@ -1,1259 +0,0 @@ -/* - * Copyright (C) 2016 Veertu Inc, - * Copyright (C) 2017 Google Inc, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -///////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2001-2012 The Bochs Project -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA -///////////////////////////////////////////////////////////////////////// - -#include "qemu/osdep.h" -#include "panic.h" -#include "x86_decode.h" -#include "x86.h" -#include "x86_emu.h" -#include "x86_mmu.h" -#include "x86_flags.h" -#include "vmcs.h" -#include "vmx.h" -#include "hvf-i386.h" - -#define EXEC_2OP_FLAGS_CMD(env, decode, cmd, FLAGS_FUNC, save_res) \ -{ \ - fetch_operands(env, decode, 2, true, true, false); \ - switch (decode->operand_size) { \ - case 1: \ - { \ - uint8_t v1 = (uint8_t)decode->op[0].val; \ - uint8_t v2 = (uint8_t)decode->op[1].val; \ - uint8_t diff = v1 cmd v2; \ - if (save_res) { \ - write_val_ext(env, decode->op[0].ptr, diff, 1); \ - } \ - FLAGS_FUNC##8(env, v1, v2, diff); \ - break; \ - } \ - case 2: \ - { \ - uint16_t v1 = (uint16_t)decode->op[0].val; \ - uint16_t v2 = (uint16_t)decode->op[1].val; \ - uint16_t diff = v1 cmd v2; \ - if (save_res) { \ - write_val_ext(env, decode->op[0].ptr, diff, 2); \ - } \ - FLAGS_FUNC##16(env, v1, v2, diff); \ - break; \ - } \ - case 4: \ - { \ - uint32_t v1 = (uint32_t)decode->op[0].val; \ - uint32_t v2 = (uint32_t)decode->op[1].val; \ - uint32_t diff = v1 cmd v2; \ - if (save_res) { \ - write_val_ext(env, decode->op[0].ptr, diff, 4); \ - } \ - FLAGS_FUNC##32(env, v1, v2, diff); \ - break; \ - } \ - default: \ - VM_PANIC("bad size\n"); \ - } \ -} \ - -target_ulong read_reg(CPUX86State *env, int reg, int size) -{ - switch (size) { - case 1: - return x86_reg(env, reg)->lx; - case 2: - return x86_reg(env, reg)->rx; - case 4: - return x86_reg(env, reg)->erx; - case 8: - return x86_reg(env, reg)->rrx; - default: - abort(); - } - return 0; -} - -void write_reg(CPUX86State *env, int reg, target_ulong val, int size) -{ - switch (size) { - case 1: - x86_reg(env, reg)->lx = val; - break; - case 2: - x86_reg(env, reg)->rx = val; - break; - case 4: - x86_reg(env, reg)->rrx = (uint32_t)val; - break; - case 8: - x86_reg(env, reg)->rrx = val; - break; - default: - abort(); - } -} - -target_ulong read_val_from_reg(target_ulong reg_ptr, int size) -{ - target_ulong val; - - switch (size) { - case 1: - val = *(uint8_t *)reg_ptr; - break; - case 2: - val = *(uint16_t *)reg_ptr; - break; - case 4: - val = *(uint32_t *)reg_ptr; - break; - case 8: - val = *(uint64_t *)reg_ptr; - break; - default: - abort(); - } - return val; -} - -void write_val_to_reg(target_ulong reg_ptr, target_ulong val, int size) -{ - switch (size) { - case 1: - *(uint8_t *)reg_ptr = val; - break; - case 2: - *(uint16_t *)reg_ptr = val; - break; - case 4: - *(uint64_t *)reg_ptr = (uint32_t)val; - break; - case 8: - *(uint64_t *)reg_ptr = val; - break; - default: - abort(); - } -} - -static bool is_host_reg(CPUX86State *env, target_ulong ptr) -{ - return (ptr - (target_ulong)&env->regs[0]) < sizeof(env->regs); -} - -void write_val_ext(CPUX86State *env, target_ulong ptr, target_ulong val, int size) -{ - if (is_host_reg(env, ptr)) { - write_val_to_reg(ptr, val, size); - return; - } - vmx_write_mem(env_cpu(env), ptr, &val, size); -} - -uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes) -{ - vmx_read_mem(env_cpu(env), env->hvf_mmio_buf, ptr, bytes); - return env->hvf_mmio_buf; -} - - -target_ulong read_val_ext(CPUX86State *env, target_ulong ptr, int size) -{ - target_ulong val; - uint8_t *mmio_ptr; - - if (is_host_reg(env, ptr)) { - return read_val_from_reg(ptr, size); - } - - mmio_ptr = read_mmio(env, ptr, size); - switch (size) { - case 1: - val = *(uint8_t *)mmio_ptr; - break; - case 2: - val = *(uint16_t *)mmio_ptr; - break; - case 4: - val = *(uint32_t *)mmio_ptr; - break; - case 8: - val = *(uint64_t *)mmio_ptr; - break; - default: - VM_PANIC("bad size\n"); - break; - } - return val; -} - -static void fetch_operands(CPUX86State *env, struct x86_decode *decode, - int n, bool val_op0, bool val_op1, bool val_op2) -{ - int i; - bool calc_val[3] = {val_op0, val_op1, val_op2}; - - for (i = 0; i < n; i++) { - switch (decode->op[i].type) { - case X86_VAR_IMMEDIATE: - break; - case X86_VAR_REG: - VM_PANIC_ON(!decode->op[i].ptr); - if (calc_val[i]) { - decode->op[i].val = read_val_from_reg(decode->op[i].ptr, - decode->operand_size); - } - break; - case X86_VAR_RM: - calc_modrm_operand(env, decode, &decode->op[i]); - if (calc_val[i]) { - decode->op[i].val = read_val_ext(env, decode->op[i].ptr, - decode->operand_size); - } - break; - case X86_VAR_OFFSET: - decode->op[i].ptr = decode_linear_addr(env, decode, - decode->op[i].ptr, - R_DS); - if (calc_val[i]) { - decode->op[i].val = read_val_ext(env, decode->op[i].ptr, - decode->operand_size); - } - break; - default: - break; - } - } -} - -static void exec_mov(CPUX86State *env, struct x86_decode *decode) -{ - fetch_operands(env, decode, 2, false, true, false); - write_val_ext(env, decode->op[0].ptr, decode->op[1].val, - decode->operand_size); - - env->eip += decode->len; -} - -static void exec_add(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, +, SET_FLAGS_OSZAPC_ADD, true); - env->eip += decode->len; -} - -static void exec_or(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, |, SET_FLAGS_OSZAPC_LOGIC, true); - env->eip += decode->len; -} - -static void exec_adc(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, +get_CF(env)+, SET_FLAGS_OSZAPC_ADD, true); - env->eip += decode->len; -} - -static void exec_sbb(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, -get_CF(env)-, SET_FLAGS_OSZAPC_SUB, true); - env->eip += decode->len; -} - -static void exec_and(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, &, SET_FLAGS_OSZAPC_LOGIC, true); - env->eip += decode->len; -} - -static void exec_sub(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, true); - env->eip += decode->len; -} - -static void exec_xor(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, ^, SET_FLAGS_OSZAPC_LOGIC, true); - env->eip += decode->len; -} - -static void exec_neg(CPUX86State *env, struct x86_decode *decode) -{ - /*EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false);*/ - int32_t val; - fetch_operands(env, decode, 2, true, true, false); - - val = 0 - sign(decode->op[1].val, decode->operand_size); - write_val_ext(env, decode->op[1].ptr, val, decode->operand_size); - - if (4 == decode->operand_size) { - SET_FLAGS_OSZAPC_SUB32(env, 0, 0 - val, val); - } else if (2 == decode->operand_size) { - SET_FLAGS_OSZAPC_SUB16(env, 0, 0 - val, val); - } else if (1 == decode->operand_size) { - SET_FLAGS_OSZAPC_SUB8(env, 0, 0 - val, val); - } else { - VM_PANIC("bad op size\n"); - } - - /*lflags_to_rflags(env);*/ - env->eip += decode->len; -} - -static void exec_cmp(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false); - env->eip += decode->len; -} - -static void exec_inc(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[1].type = X86_VAR_IMMEDIATE; - decode->op[1].val = 0; - - EXEC_2OP_FLAGS_CMD(env, decode, +1+, SET_FLAGS_OSZAP_ADD, true); - - env->eip += decode->len; -} - -static void exec_dec(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[1].type = X86_VAR_IMMEDIATE; - decode->op[1].val = 0; - - EXEC_2OP_FLAGS_CMD(env, decode, -1-, SET_FLAGS_OSZAP_SUB, true); - env->eip += decode->len; -} - -static void exec_tst(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, &, SET_FLAGS_OSZAPC_LOGIC, false); - env->eip += decode->len; -} - -static void exec_not(CPUX86State *env, struct x86_decode *decode) -{ - fetch_operands(env, decode, 1, true, false, false); - - write_val_ext(env, decode->op[0].ptr, ~decode->op[0].val, - decode->operand_size); - env->eip += decode->len; -} - -void exec_movzx(CPUX86State *env, struct x86_decode *decode) -{ - int src_op_size; - int op_size = decode->operand_size; - - fetch_operands(env, decode, 1, false, false, false); - - if (0xb6 == decode->opcode[1]) { - src_op_size = 1; - } else { - src_op_size = 2; - } - decode->operand_size = src_op_size; - calc_modrm_operand(env, decode, &decode->op[1]); - decode->op[1].val = read_val_ext(env, decode->op[1].ptr, src_op_size); - write_val_ext(env, decode->op[0].ptr, decode->op[1].val, op_size); - - env->eip += decode->len; -} - -static void exec_out(CPUX86State *env, struct x86_decode *decode) -{ - switch (decode->opcode[0]) { - case 0xe6: - hvf_handle_io(env_cpu(env), decode->op[0].val, &AL(env), 1, 1, 1); - break; - case 0xe7: - hvf_handle_io(env_cpu(env), decode->op[0].val, &RAX(env), 1, - decode->operand_size, 1); - break; - case 0xee: - hvf_handle_io(env_cpu(env), DX(env), &AL(env), 1, 1, 1); - break; - case 0xef: - hvf_handle_io(env_cpu(env), DX(env), &RAX(env), 1, - decode->operand_size, 1); - break; - default: - VM_PANIC("Bad out opcode\n"); - break; - } - env->eip += decode->len; -} - -static void exec_in(CPUX86State *env, struct x86_decode *decode) -{ - target_ulong val = 0; - switch (decode->opcode[0]) { - case 0xe4: - hvf_handle_io(env_cpu(env), decode->op[0].val, &AL(env), 0, 1, 1); - break; - case 0xe5: - hvf_handle_io(env_cpu(env), decode->op[0].val, &val, 0, - decode->operand_size, 1); - if (decode->operand_size == 2) { - AX(env) = val; - } else { - RAX(env) = (uint32_t)val; - } - break; - case 0xec: - hvf_handle_io(env_cpu(env), DX(env), &AL(env), 0, 1, 1); - break; - case 0xed: - hvf_handle_io(env_cpu(env), DX(env), &val, 0, decode->operand_size, 1); - if (decode->operand_size == 2) { - AX(env) = val; - } else { - RAX(env) = (uint32_t)val; - } - - break; - default: - VM_PANIC("Bad in opcode\n"); - break; - } - - env->eip += decode->len; -} - -static inline void string_increment_reg(CPUX86State *env, int reg, - struct x86_decode *decode) -{ - target_ulong val = read_reg(env, reg, decode->addressing_size); - if (env->eflags & DF_MASK) { - val -= decode->operand_size; - } else { - val += decode->operand_size; - } - write_reg(env, reg, val, decode->addressing_size); -} - -static inline void string_rep(CPUX86State *env, struct x86_decode *decode, - void (*func)(CPUX86State *env, - struct x86_decode *ins), int rep) -{ - target_ulong rcx = read_reg(env, R_ECX, decode->addressing_size); - while (rcx--) { - func(env, decode); - write_reg(env, R_ECX, rcx, decode->addressing_size); - if ((PREFIX_REP == rep) && !get_ZF(env)) { - break; - } - if ((PREFIX_REPN == rep) && get_ZF(env)) { - break; - } - } -} - -static void exec_ins_single(CPUX86State *env, struct x86_decode *decode) -{ - target_ulong addr = linear_addr_size(env_cpu(env), RDI(env), - decode->addressing_size, R_ES); - - hvf_handle_io(env_cpu(env), DX(env), env->hvf_mmio_buf, 0, - decode->operand_size, 1); - vmx_write_mem(env_cpu(env), addr, env->hvf_mmio_buf, - decode->operand_size); - - string_increment_reg(env, R_EDI, decode); -} - -static void exec_ins(CPUX86State *env, struct x86_decode *decode) -{ - if (decode->rep) { - string_rep(env, decode, exec_ins_single, 0); - } else { - exec_ins_single(env, decode); - } - - env->eip += decode->len; -} - -static void exec_outs_single(CPUX86State *env, struct x86_decode *decode) -{ - target_ulong addr = decode_linear_addr(env, decode, RSI(env), R_DS); - - vmx_read_mem(env_cpu(env), env->hvf_mmio_buf, addr, - decode->operand_size); - hvf_handle_io(env_cpu(env), DX(env), env->hvf_mmio_buf, 1, - decode->operand_size, 1); - - string_increment_reg(env, R_ESI, decode); -} - -static void exec_outs(CPUX86State *env, struct x86_decode *decode) -{ - if (decode->rep) { - string_rep(env, decode, exec_outs_single, 0); - } else { - exec_outs_single(env, decode); - } - - env->eip += decode->len; -} - -static void exec_movs_single(CPUX86State *env, struct x86_decode *decode) -{ - target_ulong src_addr; - target_ulong dst_addr; - target_ulong val; - - src_addr = decode_linear_addr(env, decode, RSI(env), R_DS); - dst_addr = linear_addr_size(env_cpu(env), RDI(env), - decode->addressing_size, R_ES); - - val = read_val_ext(env, src_addr, decode->operand_size); - write_val_ext(env, dst_addr, val, decode->operand_size); - - string_increment_reg(env, R_ESI, decode); - string_increment_reg(env, R_EDI, decode); -} - -static void exec_movs(CPUX86State *env, struct x86_decode *decode) -{ - if (decode->rep) { - string_rep(env, decode, exec_movs_single, 0); - } else { - exec_movs_single(env, decode); - } - - env->eip += decode->len; -} - -static void exec_cmps_single(CPUX86State *env, struct x86_decode *decode) -{ - target_ulong src_addr; - target_ulong dst_addr; - - src_addr = decode_linear_addr(env, decode, RSI(env), R_DS); - dst_addr = linear_addr_size(env_cpu(env), RDI(env), - decode->addressing_size, R_ES); - - decode->op[0].type = X86_VAR_IMMEDIATE; - decode->op[0].val = read_val_ext(env, src_addr, decode->operand_size); - decode->op[1].type = X86_VAR_IMMEDIATE; - decode->op[1].val = read_val_ext(env, dst_addr, decode->operand_size); - - EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false); - - string_increment_reg(env, R_ESI, decode); - string_increment_reg(env, R_EDI, decode); -} - -static void exec_cmps(CPUX86State *env, struct x86_decode *decode) -{ - if (decode->rep) { - string_rep(env, decode, exec_cmps_single, decode->rep); - } else { - exec_cmps_single(env, decode); - } - env->eip += decode->len; -} - - -static void exec_stos_single(CPUX86State *env, struct x86_decode *decode) -{ - target_ulong addr; - target_ulong val; - - addr = linear_addr_size(env_cpu(env), RDI(env), - decode->addressing_size, R_ES); - val = read_reg(env, R_EAX, decode->operand_size); - vmx_write_mem(env_cpu(env), addr, &val, decode->operand_size); - - string_increment_reg(env, R_EDI, decode); -} - - -static void exec_stos(CPUX86State *env, struct x86_decode *decode) -{ - if (decode->rep) { - string_rep(env, decode, exec_stos_single, 0); - } else { - exec_stos_single(env, decode); - } - - env->eip += decode->len; -} - -static void exec_scas_single(CPUX86State *env, struct x86_decode *decode) -{ - target_ulong addr; - - addr = linear_addr_size(env_cpu(env), RDI(env), - decode->addressing_size, R_ES); - decode->op[1].type = X86_VAR_IMMEDIATE; - vmx_read_mem(env_cpu(env), &decode->op[1].val, addr, decode->operand_size); - - EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false); - string_increment_reg(env, R_EDI, decode); -} - -static void exec_scas(CPUX86State *env, struct x86_decode *decode) -{ - decode->op[0].type = X86_VAR_REG; - decode->op[0].reg = R_EAX; - if (decode->rep) { - string_rep(env, decode, exec_scas_single, decode->rep); - } else { - exec_scas_single(env, decode); - } - - env->eip += decode->len; -} - -static void exec_lods_single(CPUX86State *env, struct x86_decode *decode) -{ - target_ulong addr; - target_ulong val = 0; - - addr = decode_linear_addr(env, decode, RSI(env), R_DS); - vmx_read_mem(env_cpu(env), &val, addr, decode->operand_size); - write_reg(env, R_EAX, val, decode->operand_size); - - string_increment_reg(env, R_ESI, decode); -} - -static void exec_lods(CPUX86State *env, struct x86_decode *decode) -{ - if (decode->rep) { - string_rep(env, decode, exec_lods_single, 0); - } else { - exec_lods_single(env, decode); - } - - env->eip += decode->len; -} - -void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_code) -{ - env->exception_nr = exception_index; - env->error_code = error_code; - env->has_error_code = true; - env->exception_injected = 1; -} - -static void exec_rdmsr(CPUX86State *env, struct x86_decode *decode) -{ - hvf_simulate_rdmsr(env); - env->eip += decode->len; -} - -static void exec_wrmsr(CPUX86State *env, struct x86_decode *decode) -{ - hvf_simulate_wrmsr(env); - env->eip += decode->len; -} - -/* - * flag: - * 0 - bt, 1 - btc, 2 - bts, 3 - btr - */ -static void do_bt(CPUX86State *env, struct x86_decode *decode, int flag) -{ - int32_t displacement; - uint8_t index; - bool cf; - int mask = (4 == decode->operand_size) ? 0x1f : 0xf; - - VM_PANIC_ON(decode->rex.rex); - - fetch_operands(env, decode, 2, false, true, false); - index = decode->op[1].val & mask; - - if (decode->op[0].type != X86_VAR_REG) { - if (4 == decode->operand_size) { - displacement = ((int32_t) (decode->op[1].val & 0xffffffe0)) / 32; - decode->op[0].ptr += 4 * displacement; - } else if (2 == decode->operand_size) { - displacement = ((int16_t) (decode->op[1].val & 0xfff0)) / 16; - decode->op[0].ptr += 2 * displacement; - } else { - VM_PANIC("bt 64bit\n"); - } - } - decode->op[0].val = read_val_ext(env, decode->op[0].ptr, - decode->operand_size); - cf = (decode->op[0].val >> index) & 0x01; - - switch (flag) { - case 0: - set_CF(env, cf); - return; - case 1: - decode->op[0].val ^= (1u << index); - break; - case 2: - decode->op[0].val |= (1u << index); - break; - case 3: - decode->op[0].val &= ~(1u << index); - break; - } - write_val_ext(env, decode->op[0].ptr, decode->op[0].val, - decode->operand_size); - set_CF(env, cf); -} - -static void exec_bt(CPUX86State *env, struct x86_decode *decode) -{ - do_bt(env, decode, 0); - env->eip += decode->len; -} - -static void exec_btc(CPUX86State *env, struct x86_decode *decode) -{ - do_bt(env, decode, 1); - env->eip += decode->len; -} - -static void exec_btr(CPUX86State *env, struct x86_decode *decode) -{ - do_bt(env, decode, 3); - env->eip += decode->len; -} - -static void exec_bts(CPUX86State *env, struct x86_decode *decode) -{ - do_bt(env, decode, 2); - env->eip += decode->len; -} - -void exec_shl(CPUX86State *env, struct x86_decode *decode) -{ - uint8_t count; - int of = 0, cf = 0; - - fetch_operands(env, decode, 2, true, true, false); - - count = decode->op[1].val; - count &= 0x1f; /* count is masked to 5 bits*/ - if (!count) { - goto exit; - } - - switch (decode->operand_size) { - case 1: - { - uint8_t res = 0; - if (count <= 8) { - res = (decode->op[0].val << count); - cf = (decode->op[0].val >> (8 - count)) & 0x1; - of = cf ^ (res >> 7); - } - - write_val_ext(env, decode->op[0].ptr, res, 1); - SET_FLAGS_OSZAPC_LOGIC8(env, 0, 0, res); - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - case 2: - { - uint16_t res = 0; - - /* from bochs */ - if (count <= 16) { - res = (decode->op[0].val << count); - cf = (decode->op[0].val >> (16 - count)) & 0x1; - of = cf ^ (res >> 15); /* of = cf ^ result15 */ - } - - write_val_ext(env, decode->op[0].ptr, res, 2); - SET_FLAGS_OSZAPC_LOGIC16(env, 0, 0, res); - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - case 4: - { - uint32_t res = decode->op[0].val << count; - - write_val_ext(env, decode->op[0].ptr, res, 4); - SET_FLAGS_OSZAPC_LOGIC32(env, 0, 0, res); - cf = (decode->op[0].val >> (32 - count)) & 0x1; - of = cf ^ (res >> 31); /* of = cf ^ result31 */ - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - default: - abort(); - } - -exit: - /* lflags_to_rflags(env); */ - env->eip += decode->len; -} - -void exec_movsx(CPUX86State *env, struct x86_decode *decode) -{ - int src_op_size; - int op_size = decode->operand_size; - - fetch_operands(env, decode, 2, false, false, false); - - if (0xbe == decode->opcode[1]) { - src_op_size = 1; - } else { - src_op_size = 2; - } - - decode->operand_size = src_op_size; - calc_modrm_operand(env, decode, &decode->op[1]); - decode->op[1].val = sign(read_val_ext(env, decode->op[1].ptr, src_op_size), - src_op_size); - - write_val_ext(env, decode->op[0].ptr, decode->op[1].val, op_size); - - env->eip += decode->len; -} - -void exec_ror(CPUX86State *env, struct x86_decode *decode) -{ - uint8_t count; - - fetch_operands(env, decode, 2, true, true, false); - count = decode->op[1].val; - - switch (decode->operand_size) { - case 1: - { - uint32_t bit6, bit7; - uint8_t res; - - if ((count & 0x07) == 0) { - if (count & 0x18) { - bit6 = ((uint8_t)decode->op[0].val >> 6) & 1; - bit7 = ((uint8_t)decode->op[0].val >> 7) & 1; - SET_FLAGS_OxxxxC(env, bit6 ^ bit7, bit7); - } - } else { - count &= 0x7; /* use only bottom 3 bits */ - res = ((uint8_t)decode->op[0].val >> count) | - ((uint8_t)decode->op[0].val << (8 - count)); - write_val_ext(env, decode->op[0].ptr, res, 1); - bit6 = (res >> 6) & 1; - bit7 = (res >> 7) & 1; - /* set eflags: ROR count affects the following flags: C, O */ - SET_FLAGS_OxxxxC(env, bit6 ^ bit7, bit7); - } - break; - } - case 2: - { - uint32_t bit14, bit15; - uint16_t res; - - if ((count & 0x0f) == 0) { - if (count & 0x10) { - bit14 = ((uint16_t)decode->op[0].val >> 14) & 1; - bit15 = ((uint16_t)decode->op[0].val >> 15) & 1; - /* of = result14 ^ result15 */ - SET_FLAGS_OxxxxC(env, bit14 ^ bit15, bit15); - } - } else { - count &= 0x0f; /* use only 4 LSB's */ - res = ((uint16_t)decode->op[0].val >> count) | - ((uint16_t)decode->op[0].val << (16 - count)); - write_val_ext(env, decode->op[0].ptr, res, 2); - - bit14 = (res >> 14) & 1; - bit15 = (res >> 15) & 1; - /* of = result14 ^ result15 */ - SET_FLAGS_OxxxxC(env, bit14 ^ bit15, bit15); - } - break; - } - case 4: - { - uint32_t bit31, bit30; - uint32_t res; - - count &= 0x1f; - if (count) { - res = ((uint32_t)decode->op[0].val >> count) | - ((uint32_t)decode->op[0].val << (32 - count)); - write_val_ext(env, decode->op[0].ptr, res, 4); - - bit31 = (res >> 31) & 1; - bit30 = (res >> 30) & 1; - /* of = result30 ^ result31 */ - SET_FLAGS_OxxxxC(env, bit30 ^ bit31, bit31); - } - break; - } - } - env->eip += decode->len; -} - -void exec_rol(CPUX86State *env, struct x86_decode *decode) -{ - uint8_t count; - - fetch_operands(env, decode, 2, true, true, false); - count = decode->op[1].val; - - switch (decode->operand_size) { - case 1: - { - uint32_t bit0, bit7; - uint8_t res; - - if ((count & 0x07) == 0) { - if (count & 0x18) { - bit0 = ((uint8_t)decode->op[0].val & 1); - bit7 = ((uint8_t)decode->op[0].val >> 7); - SET_FLAGS_OxxxxC(env, bit0 ^ bit7, bit0); - } - } else { - count &= 0x7; /* use only lowest 3 bits */ - res = ((uint8_t)decode->op[0].val << count) | - ((uint8_t)decode->op[0].val >> (8 - count)); - - write_val_ext(env, decode->op[0].ptr, res, 1); - /* set eflags: - * ROL count affects the following flags: C, O - */ - bit0 = (res & 1); - bit7 = (res >> 7); - SET_FLAGS_OxxxxC(env, bit0 ^ bit7, bit0); - } - break; - } - case 2: - { - uint32_t bit0, bit15; - uint16_t res; - - if ((count & 0x0f) == 0) { - if (count & 0x10) { - bit0 = ((uint16_t)decode->op[0].val & 0x1); - bit15 = ((uint16_t)decode->op[0].val >> 15); - /* of = cf ^ result15 */ - SET_FLAGS_OxxxxC(env, bit0 ^ bit15, bit0); - } - } else { - count &= 0x0f; /* only use bottom 4 bits */ - res = ((uint16_t)decode->op[0].val << count) | - ((uint16_t)decode->op[0].val >> (16 - count)); - - write_val_ext(env, decode->op[0].ptr, res, 2); - bit0 = (res & 0x1); - bit15 = (res >> 15); - /* of = cf ^ result15 */ - SET_FLAGS_OxxxxC(env, bit0 ^ bit15, bit0); - } - break; - } - case 4: - { - uint32_t bit0, bit31; - uint32_t res; - - count &= 0x1f; - if (count) { - res = ((uint32_t)decode->op[0].val << count) | - ((uint32_t)decode->op[0].val >> (32 - count)); - - write_val_ext(env, decode->op[0].ptr, res, 4); - bit0 = (res & 0x1); - bit31 = (res >> 31); - /* of = cf ^ result31 */ - SET_FLAGS_OxxxxC(env, bit0 ^ bit31, bit0); - } - break; - } - } - env->eip += decode->len; -} - - -void exec_rcl(CPUX86State *env, struct x86_decode *decode) -{ - uint8_t count; - int of = 0, cf = 0; - - fetch_operands(env, decode, 2, true, true, false); - count = decode->op[1].val & 0x1f; - - switch (decode->operand_size) { - case 1: - { - uint8_t op1_8 = decode->op[0].val; - uint8_t res; - count %= 9; - if (!count) { - break; - } - - if (1 == count) { - res = (op1_8 << 1) | get_CF(env); - } else { - res = (op1_8 << count) | (get_CF(env) << (count - 1)) | - (op1_8 >> (9 - count)); - } - - write_val_ext(env, decode->op[0].ptr, res, 1); - - cf = (op1_8 >> (8 - count)) & 0x01; - of = cf ^ (res >> 7); /* of = cf ^ result7 */ - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - case 2: - { - uint16_t res; - uint16_t op1_16 = decode->op[0].val; - - count %= 17; - if (!count) { - break; - } - - if (1 == count) { - res = (op1_16 << 1) | get_CF(env); - } else if (count == 16) { - res = (get_CF(env) << 15) | (op1_16 >> 1); - } else { /* 2..15 */ - res = (op1_16 << count) | (get_CF(env) << (count - 1)) | - (op1_16 >> (17 - count)); - } - - write_val_ext(env, decode->op[0].ptr, res, 2); - - cf = (op1_16 >> (16 - count)) & 0x1; - of = cf ^ (res >> 15); /* of = cf ^ result15 */ - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - case 4: - { - uint32_t res; - uint32_t op1_32 = decode->op[0].val; - - if (!count) { - break; - } - - if (1 == count) { - res = (op1_32 << 1) | get_CF(env); - } else { - res = (op1_32 << count) | (get_CF(env) << (count - 1)) | - (op1_32 >> (33 - count)); - } - - write_val_ext(env, decode->op[0].ptr, res, 4); - - cf = (op1_32 >> (32 - count)) & 0x1; - of = cf ^ (res >> 31); /* of = cf ^ result31 */ - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - } - env->eip += decode->len; -} - -void exec_rcr(CPUX86State *env, struct x86_decode *decode) -{ - uint8_t count; - int of = 0, cf = 0; - - fetch_operands(env, decode, 2, true, true, false); - count = decode->op[1].val & 0x1f; - - switch (decode->operand_size) { - case 1: - { - uint8_t op1_8 = decode->op[0].val; - uint8_t res; - - count %= 9; - if (!count) { - break; - } - res = (op1_8 >> count) | (get_CF(env) << (8 - count)) | - (op1_8 << (9 - count)); - - write_val_ext(env, decode->op[0].ptr, res, 1); - - cf = (op1_8 >> (count - 1)) & 0x1; - of = (((res << 1) ^ res) >> 7) & 0x1; /* of = result6 ^ result7 */ - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - case 2: - { - uint16_t op1_16 = decode->op[0].val; - uint16_t res; - - count %= 17; - if (!count) { - break; - } - res = (op1_16 >> count) | (get_CF(env) << (16 - count)) | - (op1_16 << (17 - count)); - - write_val_ext(env, decode->op[0].ptr, res, 2); - - cf = (op1_16 >> (count - 1)) & 0x1; - of = ((uint16_t)((res << 1) ^ res) >> 15) & 0x1; /* of = result15 ^ - result14 */ - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - case 4: - { - uint32_t res; - uint32_t op1_32 = decode->op[0].val; - - if (!count) { - break; - } - - if (1 == count) { - res = (op1_32 >> 1) | (get_CF(env) << 31); - } else { - res = (op1_32 >> count) | (get_CF(env) << (32 - count)) | - (op1_32 << (33 - count)); - } - - write_val_ext(env, decode->op[0].ptr, res, 4); - - cf = (op1_32 >> (count - 1)) & 0x1; - of = ((res << 1) ^ res) >> 31; /* of = result30 ^ result31 */ - SET_FLAGS_OxxxxC(env, of, cf); - break; - } - } - env->eip += decode->len; -} - -static void exec_xchg(CPUX86State *env, struct x86_decode *decode) -{ - fetch_operands(env, decode, 2, true, true, false); - - write_val_ext(env, decode->op[0].ptr, decode->op[1].val, - decode->operand_size); - write_val_ext(env, decode->op[1].ptr, decode->op[0].val, - decode->operand_size); - - env->eip += decode->len; -} - -static void exec_xadd(CPUX86State *env, struct x86_decode *decode) -{ - EXEC_2OP_FLAGS_CMD(env, decode, +, SET_FLAGS_OSZAPC_ADD, true); - write_val_ext(env, decode->op[1].ptr, decode->op[0].val, - decode->operand_size); - - env->eip += decode->len; -} - -static struct cmd_handler { - enum x86_decode_cmd cmd; - void (*handler)(CPUX86State *env, struct x86_decode *ins); -} handlers[] = { - {X86_DECODE_CMD_INVL, NULL,}, - {X86_DECODE_CMD_MOV, exec_mov}, - {X86_DECODE_CMD_ADD, exec_add}, - {X86_DECODE_CMD_OR, exec_or}, - {X86_DECODE_CMD_ADC, exec_adc}, - {X86_DECODE_CMD_SBB, exec_sbb}, - {X86_DECODE_CMD_AND, exec_and}, - {X86_DECODE_CMD_SUB, exec_sub}, - {X86_DECODE_CMD_NEG, exec_neg}, - {X86_DECODE_CMD_XOR, exec_xor}, - {X86_DECODE_CMD_CMP, exec_cmp}, - {X86_DECODE_CMD_INC, exec_inc}, - {X86_DECODE_CMD_DEC, exec_dec}, - {X86_DECODE_CMD_TST, exec_tst}, - {X86_DECODE_CMD_NOT, exec_not}, - {X86_DECODE_CMD_MOVZX, exec_movzx}, - {X86_DECODE_CMD_OUT, exec_out}, - {X86_DECODE_CMD_IN, exec_in}, - {X86_DECODE_CMD_INS, exec_ins}, - {X86_DECODE_CMD_OUTS, exec_outs}, - {X86_DECODE_CMD_RDMSR, exec_rdmsr}, - {X86_DECODE_CMD_WRMSR, exec_wrmsr}, - {X86_DECODE_CMD_BT, exec_bt}, - {X86_DECODE_CMD_BTR, exec_btr}, - {X86_DECODE_CMD_BTC, exec_btc}, - {X86_DECODE_CMD_BTS, exec_bts}, - {X86_DECODE_CMD_SHL, exec_shl}, - {X86_DECODE_CMD_ROL, exec_rol}, - {X86_DECODE_CMD_ROR, exec_ror}, - {X86_DECODE_CMD_RCR, exec_rcr}, - {X86_DECODE_CMD_RCL, exec_rcl}, - /*{X86_DECODE_CMD_CPUID, exec_cpuid},*/ - {X86_DECODE_CMD_MOVS, exec_movs}, - {X86_DECODE_CMD_CMPS, exec_cmps}, - {X86_DECODE_CMD_STOS, exec_stos}, - {X86_DECODE_CMD_SCAS, exec_scas}, - {X86_DECODE_CMD_LODS, exec_lods}, - {X86_DECODE_CMD_MOVSX, exec_movsx}, - {X86_DECODE_CMD_XCHG, exec_xchg}, - {X86_DECODE_CMD_XADD, exec_xadd}, -}; - -static struct cmd_handler _cmd_handler[X86_DECODE_CMD_LAST]; - -static void init_cmd_handler(void) -{ - int i; - for (i = 0; i < ARRAY_SIZE(handlers); i++) { - _cmd_handler[handlers[i].cmd] = handlers[i]; - } -} - -bool exec_instruction(CPUX86State *env, struct x86_decode *ins) -{ - if (!_cmd_handler[ins->cmd].handler) { - printf("Unimplemented handler (%llx) for %d (%x %x) \n", env->eip, - ins->cmd, ins->opcode[0], - ins->opcode_len > 1 ? ins->opcode[1] : 0); - env->eip += ins->len; - return true; - } - - _cmd_handler[ins->cmd].handler(env, ins); - return true; -} - -void init_emu(void) -{ - init_cmd_handler(); -} diff --git a/target/i386/hvf/x86_emu.h b/target/i386/hvf/x86_emu.h deleted file mode 100644 index bc0fc72c76..0000000000 --- a/target/i386/hvf/x86_emu.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2016 Veertu Inc, - * Copyright (C) 2017 Google Inc, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef X86_EMU_H -#define X86_EMU_H - -#include "x86.h" -#include "x86_decode.h" -#include "cpu.h" - -void init_emu(void); -bool exec_instruction(CPUX86State *env, struct x86_decode *ins); -void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_code); - -target_ulong read_reg(CPUX86State *env, int reg, int size); -void write_reg(CPUX86State *env, int reg, target_ulong val, int size); -target_ulong read_val_from_reg(target_ulong reg_ptr, int size); -void write_val_to_reg(target_ulong reg_ptr, target_ulong val, int size); -void write_val_ext(CPUX86State *env, target_ulong ptr, target_ulong val, int size); -uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes); -target_ulong read_val_ext(CPUX86State *env, target_ulong ptr, int size); - -void exec_movzx(CPUX86State *env, struct x86_decode *decode); -void exec_shl(CPUX86State *env, struct x86_decode *decode); -void exec_movsx(CPUX86State *env, struct x86_decode *decode); -void exec_ror(CPUX86State *env, struct x86_decode *decode); -void exec_rol(CPUX86State *env, struct x86_decode *decode); -void exec_rcl(CPUX86State *env, struct x86_decode *decode); -void exec_rcr(CPUX86State *env, struct x86_decode *decode); -#endif diff --git a/target/i386/hvf/x86_flags.c b/target/i386/hvf/x86_flags.c deleted file mode 100644 index 03d6de5efc..0000000000 --- a/target/i386/hvf/x86_flags.c +++ /dev/null @@ -1,313 +0,0 @@ -///////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2001-2012 The Bochs Project -// Copyright (C) 2017 Google Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA -///////////////////////////////////////////////////////////////////////// -/* - * flags functions - */ - -#include "qemu/osdep.h" - -#include "panic.h" -#include "cpu.h" -#include "x86_flags.h" -#include "x86.h" - - -/* this is basically bocsh code */ - -#define LF_SIGN_BIT 31 - -#define LF_BIT_SD (0) /* lazy Sign Flag Delta */ -#define LF_BIT_AF (3) /* lazy Adjust flag */ -#define LF_BIT_PDB (8) /* lazy Parity Delta Byte (8 bits) */ -#define LF_BIT_CF (31) /* lazy Carry Flag */ -#define LF_BIT_PO (30) /* lazy Partial Overflow = CF ^ OF */ - -#define LF_MASK_SD (0x01 << LF_BIT_SD) -#define LF_MASK_AF (0x01 << LF_BIT_AF) -#define LF_MASK_PDB (0xFF << LF_BIT_PDB) -#define LF_MASK_CF (0x01 << LF_BIT_CF) -#define LF_MASK_PO (0x01 << LF_BIT_PO) - -#define ADD_COUT_VEC(op1, op2, result) \ - (((op1) & (op2)) | (((op1) | (op2)) & (~(result)))) - -#define SUB_COUT_VEC(op1, op2, result) \ - (((~(op1)) & (op2)) | (((~(op1)) ^ (op2)) & (result))) - -#define GET_ADD_OVERFLOW(op1, op2, result, mask) \ - ((((op1) ^ (result)) & ((op2) ^ (result))) & (mask)) - -/* ******************* */ -/* OSZAPC */ -/* ******************* */ - -/* size, carries, result */ -#define SET_FLAGS_OSZAPC_SIZE(size, lf_carries, lf_result) { \ - target_ulong temp = ((lf_carries) & (LF_MASK_AF)) | \ - (((lf_carries) >> (size - 2)) << LF_BIT_PO); \ - env->hvf_lflags.result = (target_ulong)(int##size##_t)(lf_result); \ - if ((size) == 32) { \ - temp = ((lf_carries) & ~(LF_MASK_PDB | LF_MASK_SD)); \ - } else if ((size) == 16) { \ - temp = ((lf_carries) & (LF_MASK_AF)) | ((lf_carries) << 16); \ - } else if ((size) == 8) { \ - temp = ((lf_carries) & (LF_MASK_AF)) | ((lf_carries) << 24); \ - } else { \ - VM_PANIC("unimplemented"); \ - } \ - env->hvf_lflags.auxbits = (target_ulong)(uint32_t)temp; \ -} - -/* carries, result */ -#define SET_FLAGS_OSZAPC_8(carries, result) \ - SET_FLAGS_OSZAPC_SIZE(8, carries, result) -#define SET_FLAGS_OSZAPC_16(carries, result) \ - SET_FLAGS_OSZAPC_SIZE(16, carries, result) -#define SET_FLAGS_OSZAPC_32(carries, result) \ - SET_FLAGS_OSZAPC_SIZE(32, carries, result) - -/* ******************* */ -/* OSZAP */ -/* ******************* */ -/* size, carries, result */ -#define SET_FLAGS_OSZAP_SIZE(size, lf_carries, lf_result) { \ - target_ulong temp = ((lf_carries) & (LF_MASK_AF)) | \ - (((lf_carries) >> (size - 2)) << LF_BIT_PO); \ - if ((size) == 32) { \ - temp = ((lf_carries) & ~(LF_MASK_PDB | LF_MASK_SD)); \ - } else if ((size) == 16) { \ - temp = ((lf_carries) & (LF_MASK_AF)) | ((lf_carries) << 16); \ - } else if ((size) == 8) { \ - temp = ((lf_carries) & (LF_MASK_AF)) | ((lf_carries) << 24); \ - } else { \ - VM_PANIC("unimplemented"); \ - } \ - env->hvf_lflags.result = (target_ulong)(int##size##_t)(lf_result); \ - target_ulong delta_c = (env->hvf_lflags.auxbits ^ temp) & LF_MASK_CF; \ - delta_c ^= (delta_c >> 1); \ - env->hvf_lflags.auxbits = (target_ulong)(uint32_t)(temp ^ delta_c); \ -} - -/* carries, result */ -#define SET_FLAGS_OSZAP_8(carries, result) \ - SET_FLAGS_OSZAP_SIZE(8, carries, result) -#define SET_FLAGS_OSZAP_16(carries, result) \ - SET_FLAGS_OSZAP_SIZE(16, carries, result) -#define SET_FLAGS_OSZAP_32(carries, result) \ - SET_FLAGS_OSZAP_SIZE(32, carries, result) - -void SET_FLAGS_OxxxxC(CPUX86State *env, uint32_t new_of, uint32_t new_cf) -{ - uint32_t temp_po = new_of ^ new_cf; - env->hvf_lflags.auxbits &= ~(LF_MASK_PO | LF_MASK_CF); - env->hvf_lflags.auxbits |= (temp_po << LF_BIT_PO) | (new_cf << LF_BIT_CF); -} - -void SET_FLAGS_OSZAPC_SUB32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff) -{ - SET_FLAGS_OSZAPC_32(SUB_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAPC_SUB16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff) -{ - SET_FLAGS_OSZAPC_16(SUB_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAPC_SUB8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff) -{ - SET_FLAGS_OSZAPC_8(SUB_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAPC_ADD32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff) -{ - SET_FLAGS_OSZAPC_32(ADD_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAPC_ADD16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff) -{ - SET_FLAGS_OSZAPC_16(ADD_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAPC_ADD8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff) -{ - SET_FLAGS_OSZAPC_8(ADD_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAP_SUB32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff) -{ - SET_FLAGS_OSZAP_32(SUB_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAP_SUB16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff) -{ - SET_FLAGS_OSZAP_16(SUB_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAP_SUB8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff) -{ - SET_FLAGS_OSZAP_8(SUB_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAP_ADD32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff) -{ - SET_FLAGS_OSZAP_32(ADD_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAP_ADD16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff) -{ - SET_FLAGS_OSZAP_16(ADD_COUT_VEC(v1, v2, diff), diff); -} - -void SET_FLAGS_OSZAP_ADD8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff) -{ - SET_FLAGS_OSZAP_8(ADD_COUT_VEC(v1, v2, diff), diff); -} - - -void SET_FLAGS_OSZAPC_LOGIC32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff) -{ - SET_FLAGS_OSZAPC_32(0, diff); -} - -void SET_FLAGS_OSZAPC_LOGIC16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff) -{ - SET_FLAGS_OSZAPC_16(0, diff); -} - -void SET_FLAGS_OSZAPC_LOGIC8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff) -{ - SET_FLAGS_OSZAPC_8(0, diff); -} - -bool get_PF(CPUX86State *env) -{ - uint32_t temp = (255 & env->hvf_lflags.result); - temp = temp ^ (255 & (env->hvf_lflags.auxbits >> LF_BIT_PDB)); - temp = (temp ^ (temp >> 4)) & 0x0F; - return (0x9669U >> temp) & 1; -} - -void set_PF(CPUX86State *env, bool val) -{ - uint32_t temp = (255 & env->hvf_lflags.result) ^ (!val); - env->hvf_lflags.auxbits &= ~(LF_MASK_PDB); - env->hvf_lflags.auxbits |= (temp << LF_BIT_PDB); -} - -bool get_OF(CPUX86State *env) -{ - return ((env->hvf_lflags.auxbits + (1U << LF_BIT_PO)) >> LF_BIT_CF) & 1; -} - -bool get_CF(CPUX86State *env) -{ - return (env->hvf_lflags.auxbits >> LF_BIT_CF) & 1; -} - -void set_OF(CPUX86State *env, bool val) -{ - bool old_cf = get_CF(env); - SET_FLAGS_OxxxxC(env, val, old_cf); -} - -void set_CF(CPUX86State *env, bool val) -{ - bool old_of = get_OF(env); - SET_FLAGS_OxxxxC(env, old_of, val); -} - -bool get_AF(CPUX86State *env) -{ - return (env->hvf_lflags.auxbits >> LF_BIT_AF) & 1; -} - -void set_AF(CPUX86State *env, bool val) -{ - env->hvf_lflags.auxbits &= ~(LF_MASK_AF); - env->hvf_lflags.auxbits |= val << LF_BIT_AF; -} - -bool get_ZF(CPUX86State *env) -{ - return !env->hvf_lflags.result; -} - -void set_ZF(CPUX86State *env, bool val) -{ - if (val) { - env->hvf_lflags.auxbits ^= - (((env->hvf_lflags.result >> LF_SIGN_BIT) & 1) << LF_BIT_SD); - /* merge the parity bits into the Parity Delta Byte */ - uint32_t temp_pdb = (255 & env->hvf_lflags.result); - env->hvf_lflags.auxbits ^= (temp_pdb << LF_BIT_PDB); - /* now zero the .result value */ - env->hvf_lflags.result = 0; - } else { - env->hvf_lflags.result |= (1 << 8); - } -} - -bool get_SF(CPUX86State *env) -{ - return ((env->hvf_lflags.result >> LF_SIGN_BIT) ^ - (env->hvf_lflags.auxbits >> LF_BIT_SD)) & 1; -} - -void set_SF(CPUX86State *env, bool val) -{ - bool temp_sf = get_SF(env); - env->hvf_lflags.auxbits ^= (temp_sf ^ val) << LF_BIT_SD; -} - -void lflags_to_rflags(CPUX86State *env) -{ - env->eflags |= get_CF(env) ? CC_C : 0; - env->eflags |= get_PF(env) ? CC_P : 0; - env->eflags |= get_AF(env) ? CC_A : 0; - env->eflags |= get_ZF(env) ? CC_Z : 0; - env->eflags |= get_SF(env) ? CC_S : 0; - env->eflags |= get_OF(env) ? CC_O : 0; -} - -void rflags_to_lflags(CPUX86State *env) -{ - env->hvf_lflags.auxbits = env->hvf_lflags.result = 0; - set_OF(env, env->eflags & CC_O); - set_SF(env, env->eflags & CC_S); - set_ZF(env, env->eflags & CC_Z); - set_AF(env, env->eflags & CC_A); - set_PF(env, env->eflags & CC_P); - set_CF(env, env->eflags & CC_C); -} diff --git a/target/i386/hvf/x86_flags.h b/target/i386/hvf/x86_flags.h deleted file mode 100644 index 75c2a7feab..0000000000 --- a/target/i386/hvf/x86_flags.h +++ /dev/null @@ -1,81 +0,0 @@ -///////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2001-2012 The Bochs Project -// Copyright (C) 2017 Google Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA -///////////////////////////////////////////////////////////////////////// -/* - * x86 eflags functions - */ - -#ifndef X86_FLAGS_H -#define X86_FLAGS_H - -#include "cpu.h" -void lflags_to_rflags(CPUX86State *env); -void rflags_to_lflags(CPUX86State *env); - -bool get_PF(CPUX86State *env); -void set_PF(CPUX86State *env, bool val); -bool get_CF(CPUX86State *env); -void set_CF(CPUX86State *env, bool val); -bool get_AF(CPUX86State *env); -void set_AF(CPUX86State *env, bool val); -bool get_ZF(CPUX86State *env); -void set_ZF(CPUX86State *env, bool val); -bool get_SF(CPUX86State *env); -void set_SF(CPUX86State *env, bool val); -bool get_OF(CPUX86State *env); -void set_OF(CPUX86State *env, bool val); - -void SET_FLAGS_OxxxxC(CPUX86State *env, uint32_t new_of, uint32_t new_cf); - -void SET_FLAGS_OSZAPC_SUB32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff); -void SET_FLAGS_OSZAPC_SUB16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff); -void SET_FLAGS_OSZAPC_SUB8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff); - -void SET_FLAGS_OSZAPC_ADD32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff); -void SET_FLAGS_OSZAPC_ADD16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff); -void SET_FLAGS_OSZAPC_ADD8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff); - -void SET_FLAGS_OSZAP_SUB32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff); -void SET_FLAGS_OSZAP_SUB16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff); -void SET_FLAGS_OSZAP_SUB8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff); - -void SET_FLAGS_OSZAP_ADD32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff); -void SET_FLAGS_OSZAP_ADD16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff); -void SET_FLAGS_OSZAP_ADD8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff); - -void SET_FLAGS_OSZAPC_LOGIC32(CPUX86State *env, uint32_t v1, uint32_t v2, - uint32_t diff); -void SET_FLAGS_OSZAPC_LOGIC16(CPUX86State *env, uint16_t v1, uint16_t v2, - uint16_t diff); -void SET_FLAGS_OSZAPC_LOGIC8(CPUX86State *env, uint8_t v1, uint8_t v2, - uint8_t diff); - -#endif /* X86_FLAGS_H */ diff --git a/target/i386/hvf/x86_mmu.c b/target/i386/hvf/x86_mmu.c index 579d0c3a4c..afc5c17d5d 100644 --- a/target/i386/hvf/x86_mmu.c +++ b/target/i386/hvf/x86_mmu.c @@ -19,7 +19,7 @@ #include "qemu/osdep.h" #include "panic.h" #include "cpu.h" -#include "x86.h" +#include "emulate/x86.h" #include "x86_mmu.h" #include "vmcs.h" #include "vmx.h" diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c index 161217991f..bdf8b51ae6 100644 --- a/target/i386/hvf/x86_task.c +++ b/target/i386/hvf/x86_task.c @@ -14,11 +14,11 @@ #include "hvf-i386.h" #include "vmcs.h" #include "vmx.h" -#include "x86.h" +#include "emulate/x86.h" #include "x86_descr.h" #include "x86_mmu.h" -#include "x86_decode.h" -#include "x86_emu.h" +#include "emulate/x86_decode.h" +#include "emulate/x86_emu.h" #include "x86_task.h" #include "x86hvf.h" diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c index 531a340b37..2057314892 100644 --- a/target/i386/hvf/x86hvf.c +++ b/target/i386/hvf/x86hvf.c @@ -24,7 +24,7 @@ #include "vmcs.h" #include "cpu.h" #include "x86_descr.h" -#include "x86_decode.h" +#include "emulate/x86_decode.h" #include "system/hw_accel.h" #include "hw/i386/apic_internal.h" |