@@ -49,7 +49,6 @@ struct hvf_vcpu_caps {
uint64_t vmx_cap_preemption_timer;
};
-int __hvf_set_memory(hvf_slot *);
void hvf_set_phys_mem(MemoryRegionSection *, bool);
void hvf_handle_io(CPUArchState *, uint16_t, void *,
int, int, int);
@@ -58,16 +57,16 @@ hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
/* Returns 1 if HVF is available and enabled, 0 otherwise. */
int hvf_enabled(void);
-/* Disable HVF if |disable| is 1, otherwise, enable it iff it is supported by the host CPU.
- * Use hvf_enabled() after this to get the result. */
+/* Disable HVF if |disable| is 1, otherwise, enable it iff it is supported by
+ * the host CPU. Use hvf_enabled() after this to get the result. */
void hvf_disable(int disable);
-/* Returns non-0 if the host CPU supports the VMX "unrestricted guest" feature which
- * allows the virtual CPU to directly run in "real mode". If true, this allows QEMU to run
- * several vCPU threads in parallel (see cpus.c). Otherwise, only a a single TCG thread
- * can run, and it will call HVF to run the current instructions, except in case of
- * "real mode" (paging disabled, typically at boot time), or MMIO operations. */
-// int hvf_ug_platform(void); does not apply to HVF; assume we must be in UG mode
+/* Returns non-0 if the host CPU supports the VMX "unrestricted guest" feature
+ * which allows the virtual CPU to directly run in "real mode". If true, this
+ * allows QEMU to run several vCPU threads in parallel (see cpus.c). Otherwise,
+ * only a a single TCG thread can run, and it will call HVF to run the current
+ * instructions, except in case of "real mode" (paging disabled, typically at
+ * boot time), or MMIO operations. */
int hvf_sync_vcpus(void);
@@ -81,13 +80,12 @@ void _hvf_cpu_synchronize_post_init(CPUState *, run_on_cpu_data);
void hvf_vcpu_destroy(CPUState *);
void hvf_raise_event(CPUState *);
-// void hvf_reset_vcpu_state(void *opaque);
+/* void hvf_reset_vcpu_state(void *opaque); */
void vmx_reset_vcpu(CPUState *);
-void __hvf_cpu_synchronize_state(CPUState *, run_on_cpu_data);
-void __hvf_cpu_synchronize_post_reset(CPUState *, run_on_cpu_data);
void vmx_update_tpr(CPUState *);
void update_apic_tpr(CPUState *);
int hvf_put_registers(CPUState *);
+void vmx_clear_int_window_exiting(CPUState *cpu);
#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
@@ -34,44 +34,47 @@ static int hvf_disabled = 1;
static void assert_hvf_ok(hv_return_t ret)
{
- if (ret == HV_SUCCESS)
+ if (ret == HV_SUCCESS) {
return;
+ }
switch (ret) {
- case HV_ERROR:
- fprintf(stderr, "Error: HV_ERROR\n");
- break;
- case HV_BUSY:
- fprintf(stderr, "Error: HV_BUSY\n");
- break;
- case HV_BAD_ARGUMENT:
- fprintf(stderr, "Error: HV_BAD_ARGUMENT\n");
- break;
- case HV_NO_RESOURCES:
- fprintf(stderr, "Error: HV_NO_RESOURCES\n");
- break;
- case HV_NO_DEVICE:
- fprintf(stderr, "Error: HV_NO_DEVICE\n");
- break;
- case HV_UNSUPPORTED:
- fprintf(stderr, "Error: HV_UNSUPPORTED\n");
- break;
- default:
- fprintf(stderr, "Unknown Error\n");
+ case HV_ERROR:
+ fprintf(stderr, "Error: HV_ERROR\n");
+ break;
+ case HV_BUSY:
+ fprintf(stderr, "Error: HV_BUSY\n");
+ break;
+ case HV_BAD_ARGUMENT:
+ fprintf(stderr, "Error: HV_BAD_ARGUMENT\n");
+ break;
+ case HV_NO_RESOURCES:
+ fprintf(stderr, "Error: HV_NO_RESOURCES\n");
+ break;
+ case HV_NO_DEVICE:
+ fprintf(stderr, "Error: HV_NO_DEVICE\n");
+ break;
+ case HV_UNSUPPORTED:
+ fprintf(stderr, "Error: HV_UNSUPPORTED\n");
+ break;
+ default:
+ fprintf(stderr, "Unknown Error\n");
}
abort();
}
-// Memory slots/////////////////////////////////////////////////////////////////
-
-hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t end) {
+/* Memory slots */
+hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t end)
+{
hvf_slot *slot;
int x;
for (x = 0; x < hvf_state->num_slots; ++x) {
slot = &hvf_state->slots[x];
- if (slot->size && start < (slot->start + slot->size) && end > slot->start)
+ if (slot->size && start < (slot->start + slot->size) &&
+ end > slot->start) {
return slot;
+ }
}
return NULL;
}
@@ -84,13 +87,12 @@ struct mac_slot {
};
struct mac_slot mac_slots[32];
-#define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1))
+#define ALIGN(x, y) (((x) + (y) - 1) & ~((y) - 1))
-int __hvf_set_memory(hvf_slot *slot)
+static int do_hvf_set_memory(hvf_slot *slot)
{
struct mac_slot *macslot;
hv_memory_flags_t flags;
- pthread_rwlock_wrlock(&mem_lock);
hv_return_t ret;
macslot = &mac_slots[slot->slot_id];
@@ -104,7 +106,6 @@ int __hvf_set_memory(hvf_slot *slot)
}
if (!slot->size) {
- pthread_rwlock_unlock(&mem_lock);
return 0;
}
@@ -115,16 +116,17 @@ int __hvf_set_memory(hvf_slot *slot)
macslot->size = slot->size;
ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
assert_hvf_ok(ret);
- pthread_rwlock_unlock(&mem_lock);
return 0;
}
-void hvf_set_phys_mem(MemoryRegionSection* section, bool add)
+void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
{
hvf_slot *mem;
MemoryRegion *area = section->mr;
- if (!memory_region_is_ram(area)) return;
+ if (!memory_region_is_ram(area)) {
+ return;
+ }
mem = hvf_find_overlap_slot(
section->offset_within_address_space,
@@ -132,29 +134,34 @@ void hvf_set_phys_mem(MemoryRegionSection* section, bool add)
if (mem && add) {
if (mem->size == int128_get64(section->size) &&
- mem->start == section->offset_within_address_space &&
- mem->mem == (memory_region_get_ram_ptr(area) + section->offset_within_region))
- return; // Same region was attempted to register, go away.
+ mem->start == section->offset_within_address_space &&
+ mem->mem == (memory_region_get_ram_ptr(area) +
+ section->offset_within_region)) {
+ return; /* Same region was attempted to register, go away. */
+ }
}
- // Region needs to be reset. set the size to 0 and remap it.
+ /* Region needs to be reset. set the size to 0 and remap it. */
if (mem) {
mem->size = 0;
- if (__hvf_set_memory(mem)) {
+ if (do_hvf_set_memory(mem)) {
fprintf(stderr, "Failed to reset overlapping slot\n");
abort();
}
}
- if (!add) return;
+ if (!add) {
+ return;
+ }
- // Now make a new slot.
+ /* Now make a new slot. */
int x;
for (x = 0; x < hvf_state->num_slots; ++x) {
mem = &hvf_state->slots[x];
- if (!mem->size)
+ if (!mem->size) {
break;
+ }
}
if (x == hvf_state->num_slots) {
@@ -166,36 +173,26 @@ void hvf_set_phys_mem(MemoryRegionSection* section, bool add)
mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
mem->start = section->offset_within_address_space;
- if (__hvf_set_memory(mem)) {
+ if (do_hvf_set_memory(mem)) {
fprintf(stderr, "Error registering new memory slot\n");
abort();
}
}
-/* return -1 if no bit is set */
-static int get_highest_priority_int(uint32_t *tab)
-{
- int i;
- for (i = 7; i >= 0; i--) {
- if (tab[i] != 0) {
- return i * 32 + apic_fls_bit(tab[i]);
- }
- }
- return -1;
-}
-
void vmx_update_tpr(CPUState *cpu)
{
- // TODO: need integrate APIC handling
+ /* TODO: need integrate APIC handling */
X86CPU *x86_cpu = X86_CPU(cpu);
int tpr = cpu_get_apic_tpr(x86_cpu->apic_state) << 4;
int irr = apic_get_highest_priority_irr(x86_cpu->apic_state);
wreg(cpu->hvf_fd, HV_X86_TPR, tpr);
- if (irr == -1)
+ if (irr == -1) {
wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
- else
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, (irr > tpr) ? tpr >> 4 : irr >> 4);
+ } else {
+ wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, (irr > tpr) ? tpr >> 4 :
+ irr >> 4);
+ }
}
void update_apic_tpr(CPUState *cpu)
@@ -207,7 +204,7 @@ void update_apic_tpr(CPUState *cpu)
#define VECTORING_INFO_VECTOR_MASK 0xff
-// TODO: taskswitch handling
+/* TODO: taskswitch handling */
static void save_state_to_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
{
/* CR3 and ldt selector are not saved intentionally */
@@ -247,13 +244,20 @@ static void load_state_from_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
RSI(cpu) = tss->esi;
RDI(cpu) = tss->edi;
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ldt}}, REG_SEG_LDTR);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->es}}, REG_SEG_ES);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->cs}}, REG_SEG_CS);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ss}}, REG_SEG_SS);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ds}}, REG_SEG_DS);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->fs}}, REG_SEG_FS);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->gs}}, REG_SEG_GS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ldt}},
+ REG_SEG_LDTR);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->es}},
+ REG_SEG_ES);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->cs}},
+ REG_SEG_CS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ss}},
+ REG_SEG_SS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ds}},
+ REG_SEG_DS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->fs}},
+ REG_SEG_FS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->gs}},
+ REG_SEG_GS);
#if 0
load_segment(cpu, REG_SEG_LDTR, tss->ldt);
@@ -266,8 +270,10 @@ static void load_state_from_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
#endif
}
-static int task_switch_32(CPUState *cpu, x68_segment_selector tss_sel, x68_segment_selector old_tss_sel,
- uint64_t old_tss_base, struct x86_segment_descriptor *new_desc)
+static int task_switch_32(CPUState *cpu, x68_segment_selector tss_sel,
+ x68_segment_selector old_tss_sel,
+ uint64_t old_tss_base,
+ struct x86_segment_descriptor *new_desc)
{
struct x86_tss_segment32 tss_seg;
uint32_t new_tss_base = x86_segment_base(new_desc);
@@ -277,19 +283,22 @@ static int task_switch_32(CPUState *cpu, x68_segment_selector tss_sel, x68_segme
vmx_read_mem(cpu, &tss_seg, old_tss_base, sizeof(tss_seg));
save_state_to_tss32(cpu, &tss_seg);
- vmx_write_mem(cpu, old_tss_base + eip_offset, &tss_seg.eip, ldt_sel_offset - eip_offset);
+ vmx_write_mem(cpu, old_tss_base + eip_offset, &tss_seg.eip, ldt_sel_offset -
+ eip_offset);
vmx_read_mem(cpu, &tss_seg, new_tss_base, sizeof(tss_seg));
if (old_tss_sel.sel != 0xffff) {
tss_seg.prev_tss = old_tss_sel.sel;
- vmx_write_mem(cpu, new_tss_base, &tss_seg.prev_tss, sizeof(tss_seg.prev_tss));
+ vmx_write_mem(cpu, new_tss_base, &tss_seg.prev_tss,
+ sizeof(tss_seg.prev_tss));
}
load_state_from_tss32(cpu, &tss_seg);
return 0;
}
-static void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int reason, bool gate_valid, uint8_t gate, uint64_t gate_type)
+static void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel,
+ int reason, bool gate_valid, uint8_t gate, uint64_t gate_type)
{
uint64_t rip = rreg(cpu->hvf_fd, HV_X86_RIP);
if (!gate_valid || (gate_type != VMCS_INTR_T_HWEXCEPTION &&
@@ -320,12 +329,14 @@ static void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel,
dpl = task_gate_desc.dpl;
x68_segment_selector cs = vmx_read_segment_selector(cpu, REG_SEG_CS);
- if (tss_sel.rpl > dpl || cs.rpl > dpl)
- ;//DPRINTF("emulate_gp");
+ if (tss_sel.rpl > dpl || cs.rpl > dpl) {
+ VM_PANIC("emulate_gp");
+ }
}
desc_limit = x86_segment_limit(&next_tss_desc);
- if (!next_tss_desc.p || ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || desc_limit < 0x2b)) {
+ if (!next_tss_desc.p || ((desc_limit < 0x67 && (next_tss_desc.type & 8)) ||
+ desc_limit < 0x2b)) {
VM_PANIC("emulate_ts");
}
@@ -334,22 +345,27 @@ static void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel,
x86_write_segment_descriptor(cpu, &curr_tss_desc, old_tss_sel);
}
- if (reason == TSR_IRET)
+ if (reason == TSR_IRET) {
EFLAGS(cpu) &= ~RFLAGS_NT;
+ }
- if (reason != TSR_CALL && reason != TSR_IDT_GATE)
+ if (reason != TSR_CALL && reason != TSR_IDT_GATE) {
old_tss_sel.sel = 0xffff;
+ }
if (reason != TSR_IRET) {
next_tss_desc.type |= (1 << 1); /* set busy flag */
x86_write_segment_descriptor(cpu, &next_tss_desc, tss_sel);
}
- if (next_tss_desc.type & 8)
- ret = task_switch_32(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
- else
- //ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
+ if (next_tss_desc.type & 8) {
+ ret = task_switch_32(cpu, tss_sel, old_tss_sel, old_tss_base,
+ &next_tss_desc);
+ } else {
+ /*ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base,
+ * &next_tss_desc);*/
VM_PANIC("task_switch_16");
+ }
macvm_set_cr0(cpu->hvf_fd, rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0) | CR0_TS);
x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
@@ -361,7 +377,7 @@ static void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel,
hv_vcpu_flush(cpu->hvf_fd);
}
-static void hvf_handle_interrupt(CPUState * cpu, int mask)
+static void hvf_handle_interrupt(CPUState *cpu, int mask)
{
cpu->interrupt_request |= mask;
if (!qemu_cpu_is_self(cpu)) {
@@ -369,7 +385,7 @@ static void hvf_handle_interrupt(CPUState * cpu, int mask)
}
}
-void hvf_handle_io(CPUArchState * env, uint16_t port, void* buffer,
+void hvf_handle_io(CPUArchState *env, uint16_t port, void *buffer,
int direction, int size, int count)
{
int i;
@@ -382,24 +398,26 @@ void hvf_handle_io(CPUArchState * env, uint16_t port, void* buffer,
ptr += size;
}
}
-//
-// TODO: synchronize vcpu state
-void __hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
+
+/* TODO: synchronize vcpu state */
+static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
- CPUState *cpu_state = cpu;//(CPUState *)data;
- if (cpu_state->hvf_vcpu_dirty == 0)
+ CPUState *cpu_state = cpu;
+ if (cpu_state->hvf_vcpu_dirty == 0) {
hvf_get_registers(cpu_state);
+ }
cpu_state->hvf_vcpu_dirty = 1;
}
void hvf_cpu_synchronize_state(CPUState *cpu_state)
{
- if (cpu_state->hvf_vcpu_dirty == 0)
- run_on_cpu(cpu_state, __hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
+ if (cpu_state->hvf_vcpu_dirty == 0) {
+ run_on_cpu(cpu_state, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
+ }
}
-void __hvf_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
+static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
{
CPUState *cpu_state = cpu;
hvf_put_registers(cpu_state);
@@ -408,7 +426,7 @@ void __hvf_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
void hvf_cpu_synchronize_post_reset(CPUState *cpu_state)
{
- run_on_cpu(cpu_state, __hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
+ run_on_cpu(cpu_state, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
}
void _hvf_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
@@ -422,44 +440,45 @@ void hvf_cpu_synchronize_post_init(CPUState *cpu_state)
{
run_on_cpu(cpu_state, _hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
}
-
-// TODO: ept fault handlig
-void vmx_clear_int_window_exiting(CPUState *cpu);
+
+/* TODO: ept fault handlig */
static bool ept_emulation_fault(uint64_t ept_qual)
{
- int read, write;
-
- /* EPT fault on an instruction fetch doesn't make sense here */
- if (ept_qual & EPT_VIOLATION_INST_FETCH)
- return false;
-
- /* EPT fault must be a read fault or a write fault */
- read = ept_qual & EPT_VIOLATION_DATA_READ ? 1 : 0;
- write = ept_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0;
- if ((read | write) == 0)
- return false;
-
- /*
- * The EPT violation must have been caused by accessing a
- * guest-physical address that is a translation of a guest-linear
- * address.
- */
- if ((ept_qual & EPT_VIOLATION_GLA_VALID) == 0 ||
- (ept_qual & EPT_VIOLATION_XLAT_VALID) == 0) {
- return false;
- }
-
- return true;
+ int read, write;
+
+ /* EPT fault on an instruction fetch doesn't make sense here */
+ if (ept_qual & EPT_VIOLATION_INST_FETCH) {
+ return false;
+ }
+
+ /* EPT fault must be a read fault or a write fault */
+ read = ept_qual & EPT_VIOLATION_DATA_READ ? 1 : 0;
+ write = ept_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0;
+ if ((read | write) == 0) {
+ return false;
+ }
+
+ /*
+ * The EPT violation must have been caused by accessing a
+ * guest-physical address that is a translation of a guest-linear
+ * address.
+ */
+ if ((ept_qual & EPT_VIOLATION_GLA_VALID) == 0 ||
+ (ept_qual & EPT_VIOLATION_XLAT_VALID) == 0) {
+ return false;
+ }
+
+ return true;
}
-static void hvf_region_add(MemoryListener * listener,
- MemoryRegionSection * section)
+static void hvf_region_add(MemoryListener *listener,
+ MemoryRegionSection *section)
{
hvf_set_phys_mem(section, true);
}
-static void hvf_region_del(MemoryListener * listener,
- MemoryRegionSection * section)
+static void hvf_region_del(MemoryListener *listener,
+ MemoryRegionSection *section)
{
hvf_set_phys_mem(section, false);
}
@@ -470,70 +489,69 @@ static MemoryListener hvf_memory_listener = {
.region_del = hvf_region_del,
};
-static MemoryListener hvf_io_listener = {
- .priority = 10,
-};
-
void vmx_reset_vcpu(CPUState *cpu) {
+ /* TODO: this shouldn't be needed; there is already a call to
+ * cpu_synchronize_all_post_reset in vl.c
+ */
wvmcs(cpu->hvf_fd, VMCS_ENTRY_CTLS, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, 0);
macvm_set_cr0(cpu->hvf_fd, 0x60000010);
-
+
wvmcs(cpu->hvf_fd, VMCS_CR4_MASK, CR4_VMXE_MASK);
wvmcs(cpu->hvf_fd, VMCS_CR4_SHADOW, 0x0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_CR4, CR4_VMXE_MASK);
-
- // set VMCS guest state fields
+
+ /* set VMCS guest state fields */
wvmcs(cpu->hvf_fd, VMCS_GUEST_CS_SELECTOR, 0xf000);
wvmcs(cpu->hvf_fd, VMCS_GUEST_CS_LIMIT, 0xffff);
wvmcs(cpu->hvf_fd, VMCS_GUEST_CS_ACCESS_RIGHTS, 0x9b);
wvmcs(cpu->hvf_fd, VMCS_GUEST_CS_BASE, 0xffff0000);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_DS_SELECTOR, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_DS_LIMIT, 0xffff);
wvmcs(cpu->hvf_fd, VMCS_GUEST_DS_ACCESS_RIGHTS, 0x93);
wvmcs(cpu->hvf_fd, VMCS_GUEST_DS_BASE, 0);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_ES_SELECTOR, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_ES_LIMIT, 0xffff);
wvmcs(cpu->hvf_fd, VMCS_GUEST_ES_ACCESS_RIGHTS, 0x93);
wvmcs(cpu->hvf_fd, VMCS_GUEST_ES_BASE, 0);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_SELECTOR, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_LIMIT, 0xffff);
wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_ACCESS_RIGHTS, 0x93);
wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE, 0);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_SELECTOR, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_LIMIT, 0xffff);
wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_ACCESS_RIGHTS, 0x93);
wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE, 0);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_SS_SELECTOR, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_SS_LIMIT, 0xffff);
wvmcs(cpu->hvf_fd, VMCS_GUEST_SS_ACCESS_RIGHTS, 0x93);
wvmcs(cpu->hvf_fd, VMCS_GUEST_SS_BASE, 0);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_SELECTOR, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_ACCESS_RIGHTS, 0x10000);
wvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE, 0);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_TR_SELECTOR, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_TR_LIMIT, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_TR_ACCESS_RIGHTS, 0x83);
wvmcs(cpu->hvf_fd, VMCS_GUEST_TR_BASE, 0);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE, 0);
-
+
wvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_LIMIT, 0);
wvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_BASE, 0);
-
- //wvmcs(cpu->hvf_fd, VMCS_GUEST_CR2, 0x0);
+
+ /*wvmcs(cpu->hvf_fd, VMCS_GUEST_CR2, 0x0);*/
wvmcs(cpu->hvf_fd, VMCS_GUEST_CR3, 0x0);
-
+
wreg(cpu->hvf_fd, HV_X86_RIP, 0xfff0);
wreg(cpu->hvf_fd, HV_X86_RDX, 0x623);
wreg(cpu->hvf_fd, HV_X86_RFLAGS, 0x2);
@@ -544,9 +562,10 @@ void vmx_reset_vcpu(CPUState *cpu) {
wreg(cpu->hvf_fd, HV_X86_RSI, 0x0);
wreg(cpu->hvf_fd, HV_X86_RDI, 0x0);
wreg(cpu->hvf_fd, HV_X86_RBP, 0x0);
-
- for (int i = 0; i < 8; i++)
- wreg(cpu->hvf_fd, HV_X86_R8+i, 0x0);
+
+ for (int i = 0; i < 8; i++) {
+ wreg(cpu->hvf_fd, HV_X86_R8 + i, 0x0);
+ }
hv_vm_sync_tsc(0);
cpu->halted = 0;
@@ -554,7 +573,7 @@ void vmx_reset_vcpu(CPUState *cpu) {
hv_vcpu_flush(cpu->hvf_fd);
}
-void hvf_vcpu_destroy(CPUState* cpu)
+void hvf_vcpu_destroy(CPUState *cpu)
{
hv_return_t ret = hv_vcpu_destroy((hv_vcpuid_t)cpu->hvf_fd);
assert_hvf_ok(ret);
@@ -564,11 +583,12 @@ static void dummy_signal(int sig)
{
}
-int hvf_init_vcpu(CPUState * cpu) {
+int hvf_init_vcpu(CPUState *cpu)
+{
X86CPU *x86cpu;
-
- // init cpu signals
+
+ /* init cpu signals */
sigset_t set;
struct sigaction sigact;
@@ -584,42 +604,55 @@ int hvf_init_vcpu(CPUState * cpu) {
init_decoder(cpu);
init_cpuid(cpu);
- cpu->hvf_caps = (struct hvf_vcpu_caps*)g_malloc0(sizeof(struct hvf_vcpu_caps));
- cpu->hvf_x86 = (struct hvf_x86_state*)g_malloc0(sizeof(struct hvf_x86_state));
+ cpu->hvf_caps = (struct hvf_vcpu_caps *)g_malloc0(sizeof(struct hvf_vcpu_caps));
+ cpu->hvf_x86 = (struct hvf_x86_state *)g_malloc0(sizeof(struct hvf_x86_state));
r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
cpu->hvf_vcpu_dirty = 1;
assert_hvf_ok(r);
- if (hv_vmx_read_capability(HV_VMX_CAP_PINBASED, &cpu->hvf_caps->vmx_cap_pinbased))
- abort();
- if (hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, &cpu->hvf_caps->vmx_cap_procbased))
- abort();
- if (hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cpu->hvf_caps->vmx_cap_procbased2))
- abort();
- if (hv_vmx_read_capability(HV_VMX_CAP_ENTRY, &cpu->hvf_caps->vmx_cap_entry))
- abort();
-
- /* set VMCS control fields */
- wvmcs(cpu->hvf_fd, VMCS_PIN_BASED_CTLS, cap2ctrl(cpu->hvf_caps->vmx_cap_pinbased, 0));
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, cap2ctrl(cpu->hvf_caps->vmx_cap_procbased,
- VMCS_PRI_PROC_BASED_CTLS_HLT |
- VMCS_PRI_PROC_BASED_CTLS_MWAIT |
- VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET |
- VMCS_PRI_PROC_BASED_CTLS_TPR_SHADOW) |
- VMCS_PRI_PROC_BASED_CTLS_SEC_CONTROL);
- wvmcs(cpu->hvf_fd, VMCS_SEC_PROC_BASED_CTLS,
- cap2ctrl(cpu->hvf_caps->vmx_cap_procbased2,VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES));
-
- wvmcs(cpu->hvf_fd, VMCS_ENTRY_CTLS, cap2ctrl(cpu->hvf_caps->vmx_cap_entry, 0));
- wvmcs(cpu->hvf_fd, VMCS_EXCEPTION_BITMAP, 0); /* Double fault */
+ if (hv_vmx_read_capability(HV_VMX_CAP_PINBASED,
+ &cpu->hvf_caps->vmx_cap_pinbased)) {
+ abort();
+ }
+ if (hv_vmx_read_capability(HV_VMX_CAP_PROCBASED,
+ &cpu->hvf_caps->vmx_cap_procbased)) {
+ abort();
+ }
+ if (hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2,
+ &cpu->hvf_caps->vmx_cap_procbased2)) {
+ abort();
+ }
+ if (hv_vmx_read_capability(HV_VMX_CAP_ENTRY,
+ &cpu->hvf_caps->vmx_cap_entry)) {
+ abort();
+ }
+
+ /* set VMCS control fields */
+ wvmcs(cpu->hvf_fd, VMCS_PIN_BASED_CTLS,
+ cap2ctrl(cpu->hvf_caps->vmx_cap_pinbased, 0));
+ wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS,
+ cap2ctrl(cpu->hvf_caps->vmx_cap_procbased,
+ VMCS_PRI_PROC_BASED_CTLS_HLT |
+ VMCS_PRI_PROC_BASED_CTLS_MWAIT |
+ VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET |
+ VMCS_PRI_PROC_BASED_CTLS_TPR_SHADOW) |
+ VMCS_PRI_PROC_BASED_CTLS_SEC_CONTROL);
+ wvmcs(cpu->hvf_fd, VMCS_SEC_PROC_BASED_CTLS,
+ cap2ctrl(cpu->hvf_caps->vmx_cap_procbased2,
+ VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES));
+
+ wvmcs(cpu->hvf_fd, VMCS_ENTRY_CTLS, cap2ctrl(cpu->hvf_caps->vmx_cap_entry,
+ 0));
+ wvmcs(cpu->hvf_fd, VMCS_EXCEPTION_BITMAP, 0); /* Double fault */
wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
vmx_reset_vcpu(cpu);
x86cpu = X86_CPU(cpu);
- x86cpu->env.kvm_xsave_buf = qemu_memalign(4096, sizeof(struct hvf_xsave_buf));
+ x86cpu->env.kvm_xsave_buf = qemu_memalign(4096,
+ sizeof(struct hvf_xsave_buf));
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_STAR, 1);
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_LSTAR, 1);
@@ -629,7 +662,7 @@ int hvf_init_vcpu(CPUState * cpu) {
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_GSBASE, 1);
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_KERNELGSBASE, 1);
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_TSC_AUX, 1);
- //hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_TSC, 1);
+ /*hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_TSC, 1);*/
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_CS, 1);
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_EIP, 1);
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_ESP, 1);
@@ -637,12 +670,18 @@ int hvf_init_vcpu(CPUState * cpu) {
return 0;
}
-int hvf_enabled() { return !hvf_disabled; }
-void hvf_disable(int shouldDisable) {
+int hvf_enabled()
+{
+ return !hvf_disabled;
+}
+
+void hvf_disable(int shouldDisable)
+{
hvf_disabled = shouldDisable;
}
-int hvf_vcpu_exec(CPUState* cpu) {
+int hvf_vcpu_exec(CPUState *cpu)
+{
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
int ret = 0;
@@ -662,7 +701,8 @@ int hvf_vcpu_exec(CPUState* cpu) {
cpu->hvf_x86->interruptable =
!(rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &
- (VMCS_INTERRUPTIBILITY_STI_BLOCKING | VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING));
+ (VMCS_INTERRUPTIBILITY_STI_BLOCKING |
+ VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING));
hvf_inject_interrupts(cpu);
vmx_update_tpr(cpu);
@@ -680,14 +720,13 @@ int hvf_vcpu_exec(CPUState* cpu) {
/* handle VMEXIT */
uint64_t exit_reason = rvmcs(cpu->hvf_fd, VMCS_EXIT_REASON);
uint64_t exit_qual = rvmcs(cpu->hvf_fd, VMCS_EXIT_QUALIFICATION);
- uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
+ uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf_fd,
+ VMCS_EXIT_INSTRUCTION_LENGTH);
uint64_t idtvec_info = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
rip = rreg(cpu->hvf_fd, HV_X86_RIP);
RFLAGS(cpu) = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
env->eflags = RFLAGS(cpu);
- trace_hvf_vm_exit(exit_reason, exit_qual);
-
qemu_mutex_lock_iothread();
update_apic_tpr(cpu);
@@ -695,239 +734,226 @@ int hvf_vcpu_exec(CPUState* cpu) {
ret = 0;
switch (exit_reason) {
- case EXIT_REASON_HLT: {
- macvm_set_rip(cpu, rip + ins_len);
- if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) && (EFLAGS(cpu) & IF_MASK))
- && !(cpu->interrupt_request & CPU_INTERRUPT_NMI) &&
- !(idtvec_info & VMCS_IDT_VEC_VALID)) {
- cpu->halted = 1;
- ret = EXCP_HLT;
- }
- ret = EXCP_INTERRUPT;
- break;
- }
- case EXIT_REASON_MWAIT: {
- ret = EXCP_INTERRUPT;
- break;
+ case EXIT_REASON_HLT: {
+ macvm_set_rip(cpu, rip + ins_len);
+ if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (EFLAGS(cpu) & IF_MASK))
+ && !(cpu->interrupt_request & CPU_INTERRUPT_NMI) &&
+ !(idtvec_info & VMCS_IDT_VEC_VALID)) {
+ cpu->halted = 1;
+ ret = EXCP_HLT;
}
- /* Need to check if MMIO or unmmaped fault */
- case EXIT_REASON_EPT_FAULT:
- {
- hvf_slot *slot;
- addr_t gpa = rvmcs(cpu->hvf_fd, VMCS_GUEST_PHYSICAL_ADDRESS);
- trace_hvf_vm_exit_gpa(gpa);
-
- if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 && (exit_qual & EXIT_QUAL_NMIUDTI) != 0)
- vmx_set_nmi_blocking(cpu);
-
- slot = hvf_find_overlap_slot(gpa, gpa);
- // mmio
- if (ept_emulation_fault(exit_qual) && !slot) {
- struct x86_decode decode;
-
- load_regs(cpu);
- cpu->hvf_x86->fetch_rip = rip;
-
- decode_instruction(cpu, &decode);
- exec_instruction(cpu, &decode);
- store_regs(cpu);
- break;
- }
-#ifdef DIRTY_VGA_TRACKING
- if (slot) {
- bool read = exit_qual & EPT_VIOLATION_DATA_READ ? 1 : 0;
- bool write = exit_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0;
- if (!read && !write)
- break;
- int flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
- if (write) flags |= HV_MEMORY_WRITE;
-
- pthread_rwlock_wrlock(&mem_lock);
- if (write)
- mark_slot_page_dirty(slot, gpa);
- hv_vm_protect(gpa & ~0xfff, 4096, flags);
- pthread_rwlock_unlock(&mem_lock);
- }
-#endif
- break;
+ ret = EXCP_INTERRUPT;
+ break;
+ }
+ case EXIT_REASON_MWAIT: {
+ ret = EXCP_INTERRUPT;
+ break;
+ }
+ /* Need to check if MMIO or unmmaped fault */
+ case EXIT_REASON_EPT_FAULT:
+ {
+ hvf_slot *slot;
+ addr_t gpa = rvmcs(cpu->hvf_fd, VMCS_GUEST_PHYSICAL_ADDRESS);
+
+ if (((idtvec_info & VMCS_IDT_VEC_VALID) == 0) &&
+ ((exit_qual & EXIT_QUAL_NMIUDTI) != 0)) {
+ vmx_set_nmi_blocking(cpu);
}
- case EXIT_REASON_INOUT:
- {
- uint32_t in = (exit_qual & 8) != 0;
- uint32_t size = (exit_qual & 7) + 1;
- uint32_t string = (exit_qual & 16) != 0;
- uint32_t port = exit_qual >> 16;
- //uint32_t rep = (exit_qual & 0x20) != 0;
-#if 1
- if (!string && in) {
- uint64_t val = 0;
- load_regs(cpu);
- hvf_handle_io(env, port, &val, 0, size, 1);
- if (size == 1) AL(cpu) = val;
- else if (size == 2) AX(cpu) = val;
- else if (size == 4) RAX(cpu) = (uint32_t)val;
- else VM_PANIC("size");
- RIP(cpu) += ins_len;
- store_regs(cpu);
- break;
- } else if (!string && !in) {
- RAX(cpu) = rreg(cpu->hvf_fd, HV_X86_RAX);
- hvf_handle_io(env, port, &RAX(cpu), 1, size, 1);
- macvm_set_rip(cpu, rip + ins_len);
- break;
- }
-#endif
+ slot = hvf_find_overlap_slot(gpa, gpa);
+ /* mmio */
+ if (ept_emulation_fault(exit_qual) && !slot) {
struct x86_decode decode;
load_regs(cpu);
cpu->hvf_x86->fetch_rip = rip;
decode_instruction(cpu, &decode);
- VM_PANIC_ON(ins_len != decode.len);
exec_instruction(cpu, &decode);
store_regs(cpu);
-
- break;
- }
- case EXIT_REASON_CPUID: {
- uint32_t rax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
- uint32_t rbx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RBX);
- uint32_t rcx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
- uint32_t rdx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
-
- get_cpuid_func(cpu, rax, rcx, &rax, &rbx, &rcx, &rdx);
-
- wreg(cpu->hvf_fd, HV_X86_RAX, rax);
- wreg(cpu->hvf_fd, HV_X86_RBX, rbx);
- wreg(cpu->hvf_fd, HV_X86_RCX, rcx);
- wreg(cpu->hvf_fd, HV_X86_RDX, rdx);
-
- macvm_set_rip(cpu, rip + ins_len);
- break;
- }
- case EXIT_REASON_XSETBV: {
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
- uint32_t eax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
- uint32_t ecx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
- uint32_t edx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
-
- if (ecx) {
- macvm_set_rip(cpu, rip + ins_len);
- break;
- }
- env->xcr0 = ((uint64_t)edx << 32) | eax;
- wreg(cpu->hvf_fd, HV_X86_XCR0, env->xcr0 | 1);
- macvm_set_rip(cpu, rip + ins_len);
- break;
- }
- case EXIT_REASON_INTR_WINDOW:
- vmx_clear_int_window_exiting(cpu);
- ret = EXCP_INTERRUPT;
- break;
- case EXIT_REASON_NMI_WINDOW:
- vmx_clear_nmi_window_exiting(cpu);
- ret = EXCP_INTERRUPT;
- break;
- case EXIT_REASON_EXT_INTR:
- /* force exit and allow io handling */
- ret = EXCP_INTERRUPT;
- break;
- case EXIT_REASON_RDMSR:
- case EXIT_REASON_WRMSR:
- {
- load_regs(cpu);
- if (exit_reason == EXIT_REASON_RDMSR)
- simulate_rdmsr(cpu);
- else
- simulate_wrmsr(cpu);
- RIP(cpu) += rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
- store_regs(cpu);
break;
}
- case EXIT_REASON_CR_ACCESS: {
- int cr;
- int reg;
+#ifdef DIRTY_VGA_TRACKING
+ /* TODO: handle dirty page tracking */
+#endif
+ break;
+ }
+ case EXIT_REASON_INOUT:
+ {
+ uint32_t in = (exit_qual & 8) != 0;
+ uint32_t size = (exit_qual & 7) + 1;
+ uint32_t string = (exit_qual & 16) != 0;
+ uint32_t port = exit_qual >> 16;
+ /*uint32_t rep = (exit_qual & 0x20) != 0;*/
+#if 1
+ if (!string && in) {
+ uint64_t val = 0;
load_regs(cpu);
- cr = exit_qual & 15;
- reg = (exit_qual >> 8) & 15;
-
- switch (cr) {
- case 0x0: {
- macvm_set_cr0(cpu->hvf_fd, RRX(cpu, reg));
- break;
- }
- case 4: {
- macvm_set_cr4(cpu->hvf_fd, RRX(cpu, reg));
- break;
- }
- case 8: {
- X86CPU *x86_cpu = X86_CPU(cpu);
- if (exit_qual & 0x10) {
- RRX(cpu, reg) = cpu_get_apic_tpr(x86_cpu->apic_state);
- }
- else {
- int tpr = RRX(cpu, reg);
- cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
- ret = EXCP_INTERRUPT;
- }
- break;
- }
- default:
- fprintf(stderr, "Unrecognized CR %d\n", cr);
- abort();
+ hvf_handle_io(env, port, &val, 0, size, 1);
+ if (size == 1) {
+ AL(cpu) = val;
+ } else if (size == 2) {
+ AX(cpu) = val;
+ } else if (size == 4) {
+ RAX(cpu) = (uint32_t)val;
+ } else {
+ VM_PANIC("size");
}
RIP(cpu) += ins_len;
store_regs(cpu);
break;
+ } else if (!string && !in) {
+ RAX(cpu) = rreg(cpu->hvf_fd, HV_X86_RAX);
+ hvf_handle_io(env, port, &RAX(cpu), 1, size, 1);
+ macvm_set_rip(cpu, rip + ins_len);
+ break;
}
- case EXIT_REASON_APIC_ACCESS: { // TODO
- struct x86_decode decode;
+#endif
+ struct x86_decode decode;
- load_regs(cpu);
- cpu->hvf_x86->fetch_rip = rip;
+ load_regs(cpu);
+ cpu->hvf_x86->fetch_rip = rip;
- decode_instruction(cpu, &decode);
- exec_instruction(cpu, &decode);
- store_regs(cpu);
+ decode_instruction(cpu, &decode);
+ VM_PANIC_ON(ins_len != decode.len);
+ exec_instruction(cpu, &decode);
+ store_regs(cpu);
+
+ break;
+ }
+ case EXIT_REASON_CPUID: {
+ uint32_t rax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
+ uint32_t rbx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RBX);
+ uint32_t rcx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
+ uint32_t rdx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
+
+ cpu_x86_cpuid(cpu, rax, rcx, &rax, &rbx, &rcx, &rdx);
+
+ wreg(cpu->hvf_fd, HV_X86_RAX, rax);
+ wreg(cpu->hvf_fd, HV_X86_RBX, rbx);
+ wreg(cpu->hvf_fd, HV_X86_RCX, rcx);
+ wreg(cpu->hvf_fd, HV_X86_RDX, rdx);
+
+ macvm_set_rip(cpu, rip + ins_len);
+ break;
+ }
+ case EXIT_REASON_XSETBV: {
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+ uint32_t eax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
+ uint32_t ecx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
+ uint32_t edx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
+
+ if (ecx) {
+ macvm_set_rip(cpu, rip + ins_len);
break;
}
- case EXIT_REASON_TPR: {
- ret = 1;
- break;
+ env->xcr0 = ((uint64_t)edx << 32) | eax;
+ wreg(cpu->hvf_fd, HV_X86_XCR0, env->xcr0 | 1);
+ macvm_set_rip(cpu, rip + ins_len);
+ break;
+ }
+ case EXIT_REASON_INTR_WINDOW:
+ vmx_clear_int_window_exiting(cpu);
+ ret = EXCP_INTERRUPT;
+ break;
+ case EXIT_REASON_NMI_WINDOW:
+ vmx_clear_nmi_window_exiting(cpu);
+ ret = EXCP_INTERRUPT;
+ break;
+ case EXIT_REASON_EXT_INTR:
+ /* force exit and allow io handling */
+ ret = EXCP_INTERRUPT;
+ break;
+ case EXIT_REASON_RDMSR:
+ case EXIT_REASON_WRMSR:
+ {
+ load_regs(cpu);
+ if (exit_reason == EXIT_REASON_RDMSR) {
+ simulate_rdmsr(cpu);
+ } else {
+ simulate_wrmsr(cpu);
}
- case EXIT_REASON_TASK_SWITCH: {
- uint64_t vinfo = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
- x68_segment_selector sel = {.sel = exit_qual & 0xffff};
- vmx_handle_task_switch(cpu, sel, (exit_qual >> 30) & 0x3,
- vinfo & VMCS_INTR_VALID, vinfo & VECTORING_INFO_VECTOR_MASK, vinfo & VMCS_INTR_T_MASK);
+ RIP(cpu) += rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
+ store_regs(cpu);
+ break;
+ }
+ case EXIT_REASON_CR_ACCESS: {
+ int cr;
+ int reg;
+
+ load_regs(cpu);
+ cr = exit_qual & 15;
+ reg = (exit_qual >> 8) & 15;
+
+ switch (cr) {
+ case 0x0: {
+ macvm_set_cr0(cpu->hvf_fd, RRX(cpu, reg));
break;
}
- case EXIT_REASON_TRIPLE_FAULT: {
- //addr_t gpa = rvmcs(cpu->hvf_fd, VMCS_GUEST_PHYSICAL_ADDRESS);
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
- usleep(1000 * 100);
- ret = EXCP_INTERRUPT;
+ case 4: {
+ macvm_set_cr4(cpu->hvf_fd, RRX(cpu, reg));
break;
}
- case EXIT_REASON_RDPMC:
- wreg(cpu->hvf_fd, HV_X86_RAX, 0);
- wreg(cpu->hvf_fd, HV_X86_RDX, 0);
- macvm_set_rip(cpu, rip + ins_len);
- break;
- case VMX_REASON_VMCALL:
- // TODO: maybe just take this out?
- // if (g_hypervisor_iface) {
- // load_regs(cpu);
- // g_hypervisor_iface->hypercall_handler(cpu);
- // RIP(cpu) += rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
- // store_regs(cpu);
- // }
+ case 8: {
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ if (exit_qual & 0x10) {
+ RRX(cpu, reg) = cpu_get_apic_tpr(x86_cpu->apic_state);
+ } else {
+ int tpr = RRX(cpu, reg);
+ cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
+ ret = EXCP_INTERRUPT;
+ }
break;
+ }
default:
- fprintf(stderr, "%llx: unhandled exit %llx\n", rip, exit_reason);
+ fprintf(stderr, "Unrecognized CR %d\n", cr);
+ abort();
+ }
+ RIP(cpu) += ins_len;
+ store_regs(cpu);
+ break;
+ }
+ case EXIT_REASON_APIC_ACCESS: { /* TODO */
+ struct x86_decode decode;
+
+ load_regs(cpu);
+ cpu->hvf_x86->fetch_rip = rip;
+
+ decode_instruction(cpu, &decode);
+ exec_instruction(cpu, &decode);
+ store_regs(cpu);
+ break;
+ }
+ case EXIT_REASON_TPR: {
+ ret = 1;
+ break;
+ }
+ case EXIT_REASON_TASK_SWITCH: {
+ uint64_t vinfo = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
+ x68_segment_selector sel = {.sel = exit_qual & 0xffff};
+ vmx_handle_task_switch(cpu, sel, (exit_qual >> 30) & 0x3,
+ vinfo & VMCS_INTR_VALID, vinfo & VECTORING_INFO_VECTOR_MASK, vinfo
+ & VMCS_INTR_T_MASK);
+ break;
+ }
+ case EXIT_REASON_TRIPLE_FAULT: {
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+ ret = EXCP_INTERRUPT;
+ break;
+ }
+ case EXIT_REASON_RDPMC:
+ wreg(cpu->hvf_fd, HV_X86_RAX, 0);
+ wreg(cpu->hvf_fd, HV_X86_RDX, 0);
+ macvm_set_rip(cpu, rip + ins_len);
+ break;
+ case VMX_REASON_VMCALL:
+ /* TODO: inject #GP fault */
+ break;
+ default:
+ fprintf(stderr, "%llx: unhandled exit %llx\n", rip, exit_reason);
}
} while (ret == 0);
@@ -946,17 +972,16 @@ static int hvf_accel_init(MachineState *ms)
assert_hvf_ok(ret);
s = (HVFState *)g_malloc0(sizeof(HVFState));
-
+
s->num_slots = 32;
for (x = 0; x < s->num_slots; ++x) {
s->slots[x].size = 0;
s->slots[x].slot_id = x;
}
-
+
hvf_state = s;
cpu_interrupt_handler = hvf_handle_interrupt;
memory_listener_register(&hvf_memory_listener, &address_space_memory);
- memory_listener_register(&hvf_io_listener, &address_space_io);
return 0;
}
@@ -41,7 +41,7 @@ struct hvf_state {
/* Functions exported to host specific mode */
/* Host specific functions */
-int hvf_inject_interrupt(CPUArchState * env, int vector);
+int hvf_inject_interrupt(CPUArchState *env, int vector);
int hvf_vcpu_run(struct hvf_vcpu_state *vcpu);
#endif
@@ -27,326 +27,326 @@
*/
#ifndef _VMCS_H_
-#define _VMCS_H_
+#define _VMCS_H_
#include <Hypervisor/hv.h>
#include <Hypervisor/hv_vmx.h>
-#define VMCS_INITIAL 0xffffffffffffffff
+#define VMCS_INITIAL 0xffffffffffffffff
-#define VMCS_IDENT(encoding) ((encoding) | 0x80000000)
+#define VMCS_IDENT(encoding) ((encoding) | 0x80000000)
/*
* VMCS field encodings from Appendix H, Intel Architecture Manual Vol3B.
*/
-#define VMCS_INVALID_ENCODING 0xffffffff
+#define VMCS_INVALID_ENCODING 0xffffffff
/* 16-bit control fields */
-#define VMCS_VPID 0x00000000
-#define VMCS_PIR_VECTOR 0x00000002
+#define VMCS_VPID 0x00000000
+#define VMCS_PIR_VECTOR 0x00000002
/* 16-bit guest-state fields */
-#define VMCS_GUEST_ES_SELECTOR 0x00000800
-#define VMCS_GUEST_CS_SELECTOR 0x00000802
-#define VMCS_GUEST_SS_SELECTOR 0x00000804
-#define VMCS_GUEST_DS_SELECTOR 0x00000806
-#define VMCS_GUEST_FS_SELECTOR 0x00000808
-#define VMCS_GUEST_GS_SELECTOR 0x0000080A
-#define VMCS_GUEST_LDTR_SELECTOR 0x0000080C
-#define VMCS_GUEST_TR_SELECTOR 0x0000080E
-#define VMCS_GUEST_INTR_STATUS 0x00000810
+#define VMCS_GUEST_ES_SELECTOR 0x00000800
+#define VMCS_GUEST_CS_SELECTOR 0x00000802
+#define VMCS_GUEST_SS_SELECTOR 0x00000804
+#define VMCS_GUEST_DS_SELECTOR 0x00000806
+#define VMCS_GUEST_FS_SELECTOR 0x00000808
+#define VMCS_GUEST_GS_SELECTOR 0x0000080A
+#define VMCS_GUEST_LDTR_SELECTOR 0x0000080C
+#define VMCS_GUEST_TR_SELECTOR 0x0000080E
+#define VMCS_GUEST_INTR_STATUS 0x00000810
/* 16-bit host-state fields */
-#define VMCS_HOST_ES_SELECTOR 0x00000C00
-#define VMCS_HOST_CS_SELECTOR 0x00000C02
-#define VMCS_HOST_SS_SELECTOR 0x00000C04
-#define VMCS_HOST_DS_SELECTOR 0x00000C06
-#define VMCS_HOST_FS_SELECTOR 0x00000C08
-#define VMCS_HOST_GS_SELECTOR 0x00000C0A
-#define VMCS_HOST_TR_SELECTOR 0x00000C0C
+#define VMCS_HOST_ES_SELECTOR 0x00000C00
+#define VMCS_HOST_CS_SELECTOR 0x00000C02
+#define VMCS_HOST_SS_SELECTOR 0x00000C04
+#define VMCS_HOST_DS_SELECTOR 0x00000C06
+#define VMCS_HOST_FS_SELECTOR 0x00000C08
+#define VMCS_HOST_GS_SELECTOR 0x00000C0A
+#define VMCS_HOST_TR_SELECTOR 0x00000C0C
/* 64-bit control fields */
-#define VMCS_IO_BITMAP_A 0x00002000
-#define VMCS_IO_BITMAP_B 0x00002002
-#define VMCS_MSR_BITMAP 0x00002004
-#define VMCS_EXIT_MSR_STORE 0x00002006
-#define VMCS_EXIT_MSR_LOAD 0x00002008
-#define VMCS_ENTRY_MSR_LOAD 0x0000200A
-#define VMCS_EXECUTIVE_VMCS 0x0000200C
-#define VMCS_TSC_OFFSET 0x00002010
-#define VMCS_VIRTUAL_APIC 0x00002012
-#define VMCS_APIC_ACCESS 0x00002014
-#define VMCS_PIR_DESC 0x00002016
-#define VMCS_EPTP 0x0000201A
-#define VMCS_EOI_EXIT0 0x0000201C
-#define VMCS_EOI_EXIT1 0x0000201E
-#define VMCS_EOI_EXIT2 0x00002020
-#define VMCS_EOI_EXIT3 0x00002022
-#define VMCS_EOI_EXIT(vector) (VMCS_EOI_EXIT0 + ((vector) / 64) * 2)
+#define VMCS_IO_BITMAP_A 0x00002000
+#define VMCS_IO_BITMAP_B 0x00002002
+#define VMCS_MSR_BITMAP 0x00002004
+#define VMCS_EXIT_MSR_STORE 0x00002006
+#define VMCS_EXIT_MSR_LOAD 0x00002008
+#define VMCS_ENTRY_MSR_LOAD 0x0000200A
+#define VMCS_EXECUTIVE_VMCS 0x0000200C
+#define VMCS_TSC_OFFSET 0x00002010
+#define VMCS_VIRTUAL_APIC 0x00002012
+#define VMCS_APIC_ACCESS 0x00002014
+#define VMCS_PIR_DESC 0x00002016
+#define VMCS_EPTP 0x0000201A
+#define VMCS_EOI_EXIT0 0x0000201C
+#define VMCS_EOI_EXIT1 0x0000201E
+#define VMCS_EOI_EXIT2 0x00002020
+#define VMCS_EOI_EXIT3 0x00002022
+#define VMCS_EOI_EXIT(vector) (VMCS_EOI_EXIT0 + ((vector) / 64) * 2)
/* 64-bit read-only fields */
-#define VMCS_GUEST_PHYSICAL_ADDRESS 0x00002400
+#define VMCS_GUEST_PHYSICAL_ADDRESS 0x00002400
/* 64-bit guest-state fields */
-#define VMCS_LINK_POINTER 0x00002800
-#define VMCS_GUEST_IA32_DEBUGCTL 0x00002802
-#define VMCS_GUEST_IA32_PAT 0x00002804
-#define VMCS_GUEST_IA32_EFER 0x00002806
-#define VMCS_GUEST_IA32_PERF_GLOBAL_CTRL 0x00002808
-#define VMCS_GUEST_PDPTE0 0x0000280A
-#define VMCS_GUEST_PDPTE1 0x0000280C
-#define VMCS_GUEST_PDPTE2 0x0000280E
-#define VMCS_GUEST_PDPTE3 0x00002810
+#define VMCS_LINK_POINTER 0x00002800
+#define VMCS_GUEST_IA32_DEBUGCTL 0x00002802
+#define VMCS_GUEST_IA32_PAT 0x00002804
+#define VMCS_GUEST_IA32_EFER 0x00002806
+#define VMCS_GUEST_IA32_PERF_GLOBAL_CTRL 0x00002808
+#define VMCS_GUEST_PDPTE0 0x0000280A
+#define VMCS_GUEST_PDPTE1 0x0000280C
+#define VMCS_GUEST_PDPTE2 0x0000280E
+#define VMCS_GUEST_PDPTE3 0x00002810
/* 64-bit host-state fields */
-#define VMCS_HOST_IA32_PAT 0x00002C00
-#define VMCS_HOST_IA32_EFER 0x00002C02
-#define VMCS_HOST_IA32_PERF_GLOBAL_CTRL 0x00002C04
+#define VMCS_HOST_IA32_PAT 0x00002C00
+#define VMCS_HOST_IA32_EFER 0x00002C02
+#define VMCS_HOST_IA32_PERF_GLOBAL_CTRL 0x00002C04
/* 32-bit control fields */
-#define VMCS_PIN_BASED_CTLS 0x00004000
-#define VMCS_PRI_PROC_BASED_CTLS 0x00004002
-#define VMCS_EXCEPTION_BITMAP 0x00004004
-#define VMCS_PF_ERROR_MASK 0x00004006
-#define VMCS_PF_ERROR_MATCH 0x00004008
-#define VMCS_CR3_TARGET_COUNT 0x0000400A
-#define VMCS_EXIT_CTLS 0x0000400C
-#define VMCS_EXIT_MSR_STORE_COUNT 0x0000400E
-#define VMCS_EXIT_MSR_LOAD_COUNT 0x00004010
-#define VMCS_ENTRY_CTLS 0x00004012
-#define VMCS_ENTRY_MSR_LOAD_COUNT 0x00004014
-#define VMCS_ENTRY_INTR_INFO 0x00004016
-#define VMCS_ENTRY_EXCEPTION_ERROR 0x00004018
-#define VMCS_ENTRY_INST_LENGTH 0x0000401A
-#define VMCS_TPR_THRESHOLD 0x0000401C
-#define VMCS_SEC_PROC_BASED_CTLS 0x0000401E
-#define VMCS_PLE_GAP 0x00004020
-#define VMCS_PLE_WINDOW 0x00004022
+#define VMCS_PIN_BASED_CTLS 0x00004000
+#define VMCS_PRI_PROC_BASED_CTLS 0x00004002
+#define VMCS_EXCEPTION_BITMAP 0x00004004
+#define VMCS_PF_ERROR_MASK 0x00004006
+#define VMCS_PF_ERROR_MATCH 0x00004008
+#define VMCS_CR3_TARGET_COUNT 0x0000400A
+#define VMCS_EXIT_CTLS 0x0000400C
+#define VMCS_EXIT_MSR_STORE_COUNT 0x0000400E
+#define VMCS_EXIT_MSR_LOAD_COUNT 0x00004010
+#define VMCS_ENTRY_CTLS 0x00004012
+#define VMCS_ENTRY_MSR_LOAD_COUNT 0x00004014
+#define VMCS_ENTRY_INTR_INFO 0x00004016
+#define VMCS_ENTRY_EXCEPTION_ERROR 0x00004018
+#define VMCS_ENTRY_INST_LENGTH 0x0000401A
+#define VMCS_TPR_THRESHOLD 0x0000401C
+#define VMCS_SEC_PROC_BASED_CTLS 0x0000401E
+#define VMCS_PLE_GAP 0x00004020
+#define VMCS_PLE_WINDOW 0x00004022
/* 32-bit read-only data fields */
-#define VMCS_INSTRUCTION_ERROR 0x00004400
-#define VMCS_EXIT_REASON 0x00004402
-#define VMCS_EXIT_INTR_INFO 0x00004404
-#define VMCS_EXIT_INTR_ERRCODE 0x00004406
-#define VMCS_IDT_VECTORING_INFO 0x00004408
-#define VMCS_IDT_VECTORING_ERROR 0x0000440A
-#define VMCS_EXIT_INSTRUCTION_LENGTH 0x0000440C
-#define VMCS_EXIT_INSTRUCTION_INFO 0x0000440E
+#define VMCS_INSTRUCTION_ERROR 0x00004400
+#define VMCS_EXIT_REASON 0x00004402
+#define VMCS_EXIT_INTR_INFO 0x00004404
+#define VMCS_EXIT_INTR_ERRCODE 0x00004406
+#define VMCS_IDT_VECTORING_INFO 0x00004408
+#define VMCS_IDT_VECTORING_ERROR 0x0000440A
+#define VMCS_EXIT_INSTRUCTION_LENGTH 0x0000440C
+#define VMCS_EXIT_INSTRUCTION_INFO 0x0000440E
/* 32-bit guest-state fields */
-#define VMCS_GUEST_ES_LIMIT 0x00004800
-#define VMCS_GUEST_CS_LIMIT 0x00004802
-#define VMCS_GUEST_SS_LIMIT 0x00004804
-#define VMCS_GUEST_DS_LIMIT 0x00004806
-#define VMCS_GUEST_FS_LIMIT 0x00004808
-#define VMCS_GUEST_GS_LIMIT 0x0000480A
-#define VMCS_GUEST_LDTR_LIMIT 0x0000480C
-#define VMCS_GUEST_TR_LIMIT 0x0000480E
-#define VMCS_GUEST_GDTR_LIMIT 0x00004810
-#define VMCS_GUEST_IDTR_LIMIT 0x00004812
-#define VMCS_GUEST_ES_ACCESS_RIGHTS 0x00004814
-#define VMCS_GUEST_CS_ACCESS_RIGHTS 0x00004816
-#define VMCS_GUEST_SS_ACCESS_RIGHTS 0x00004818
-#define VMCS_GUEST_DS_ACCESS_RIGHTS 0x0000481A
-#define VMCS_GUEST_FS_ACCESS_RIGHTS 0x0000481C
-#define VMCS_GUEST_GS_ACCESS_RIGHTS 0x0000481E
-#define VMCS_GUEST_LDTR_ACCESS_RIGHTS 0x00004820
-#define VMCS_GUEST_TR_ACCESS_RIGHTS 0x00004822
-#define VMCS_GUEST_INTERRUPTIBILITY 0x00004824
-#define VMCS_GUEST_ACTIVITY 0x00004826
-#define VMCS_GUEST_SMBASE 0x00004828
-#define VMCS_GUEST_IA32_SYSENTER_CS 0x0000482A
-#define VMCS_PREEMPTION_TIMER_VALUE 0x0000482E
+#define VMCS_GUEST_ES_LIMIT 0x00004800
+#define VMCS_GUEST_CS_LIMIT 0x00004802
+#define VMCS_GUEST_SS_LIMIT 0x00004804
+#define VMCS_GUEST_DS_LIMIT 0x00004806
+#define VMCS_GUEST_FS_LIMIT 0x00004808
+#define VMCS_GUEST_GS_LIMIT 0x0000480A
+#define VMCS_GUEST_LDTR_LIMIT 0x0000480C
+#define VMCS_GUEST_TR_LIMIT 0x0000480E
+#define VMCS_GUEST_GDTR_LIMIT 0x00004810
+#define VMCS_GUEST_IDTR_LIMIT 0x00004812
+#define VMCS_GUEST_ES_ACCESS_RIGHTS 0x00004814
+#define VMCS_GUEST_CS_ACCESS_RIGHTS 0x00004816
+#define VMCS_GUEST_SS_ACCESS_RIGHTS 0x00004818
+#define VMCS_GUEST_DS_ACCESS_RIGHTS 0x0000481A
+#define VMCS_GUEST_FS_ACCESS_RIGHTS 0x0000481C
+#define VMCS_GUEST_GS_ACCESS_RIGHTS 0x0000481E
+#define VMCS_GUEST_LDTR_ACCESS_RIGHTS 0x00004820
+#define VMCS_GUEST_TR_ACCESS_RIGHTS 0x00004822
+#define VMCS_GUEST_INTERRUPTIBILITY 0x00004824
+#define VMCS_GUEST_ACTIVITY 0x00004826
+#define VMCS_GUEST_SMBASE 0x00004828
+#define VMCS_GUEST_IA32_SYSENTER_CS 0x0000482A
+#define VMCS_PREEMPTION_TIMER_VALUE 0x0000482E
/* 32-bit host state fields */
-#define VMCS_HOST_IA32_SYSENTER_CS 0x00004C00
+#define VMCS_HOST_IA32_SYSENTER_CS 0x00004C00
/* Natural Width control fields */
-#define VMCS_CR0_MASK 0x00006000
-#define VMCS_CR4_MASK 0x00006002
-#define VMCS_CR0_SHADOW 0x00006004
-#define VMCS_CR4_SHADOW 0x00006006
-#define VMCS_CR3_TARGET0 0x00006008
-#define VMCS_CR3_TARGET1 0x0000600A
-#define VMCS_CR3_TARGET2 0x0000600C
-#define VMCS_CR3_TARGET3 0x0000600E
+#define VMCS_CR0_MASK 0x00006000
+#define VMCS_CR4_MASK 0x00006002
+#define VMCS_CR0_SHADOW 0x00006004
+#define VMCS_CR4_SHADOW 0x00006006
+#define VMCS_CR3_TARGET0 0x00006008
+#define VMCS_CR3_TARGET1 0x0000600A
+#define VMCS_CR3_TARGET2 0x0000600C
+#define VMCS_CR3_TARGET3 0x0000600E
/* Natural Width read-only fields */
-#define VMCS_EXIT_QUALIFICATION 0x00006400
-#define VMCS_IO_RCX 0x00006402
-#define VMCS_IO_RSI 0x00006404
-#define VMCS_IO_RDI 0x00006406
-#define VMCS_IO_RIP 0x00006408
-#define VMCS_GUEST_LINEAR_ADDRESS 0x0000640A
+#define VMCS_EXIT_QUALIFICATION 0x00006400
+#define VMCS_IO_RCX 0x00006402
+#define VMCS_IO_RSI 0x00006404
+#define VMCS_IO_RDI 0x00006406
+#define VMCS_IO_RIP 0x00006408
+#define VMCS_GUEST_LINEAR_ADDRESS 0x0000640A
/* Natural Width guest-state fields */
-#define VMCS_GUEST_CR0 0x00006800
-#define VMCS_GUEST_CR3 0x00006802
-#define VMCS_GUEST_CR4 0x00006804
-#define VMCS_GUEST_ES_BASE 0x00006806
-#define VMCS_GUEST_CS_BASE 0x00006808
-#define VMCS_GUEST_SS_BASE 0x0000680A
-#define VMCS_GUEST_DS_BASE 0x0000680C
-#define VMCS_GUEST_FS_BASE 0x0000680E
-#define VMCS_GUEST_GS_BASE 0x00006810
-#define VMCS_GUEST_LDTR_BASE 0x00006812
-#define VMCS_GUEST_TR_BASE 0x00006814
-#define VMCS_GUEST_GDTR_BASE 0x00006816
-#define VMCS_GUEST_IDTR_BASE 0x00006818
-#define VMCS_GUEST_DR7 0x0000681A
-#define VMCS_GUEST_RSP 0x0000681C
-#define VMCS_GUEST_RIP 0x0000681E
-#define VMCS_GUEST_RFLAGS 0x00006820
-#define VMCS_GUEST_PENDING_DBG_EXCEPTIONS 0x00006822
-#define VMCS_GUEST_IA32_SYSENTER_ESP 0x00006824
-#define VMCS_GUEST_IA32_SYSENTER_EIP 0x00006826
+#define VMCS_GUEST_CR0 0x00006800
+#define VMCS_GUEST_CR3 0x00006802
+#define VMCS_GUEST_CR4 0x00006804
+#define VMCS_GUEST_ES_BASE 0x00006806
+#define VMCS_GUEST_CS_BASE 0x00006808
+#define VMCS_GUEST_SS_BASE 0x0000680A
+#define VMCS_GUEST_DS_BASE 0x0000680C
+#define VMCS_GUEST_FS_BASE 0x0000680E
+#define VMCS_GUEST_GS_BASE 0x00006810
+#define VMCS_GUEST_LDTR_BASE 0x00006812
+#define VMCS_GUEST_TR_BASE 0x00006814
+#define VMCS_GUEST_GDTR_BASE 0x00006816
+#define VMCS_GUEST_IDTR_BASE 0x00006818
+#define VMCS_GUEST_DR7 0x0000681A
+#define VMCS_GUEST_RSP 0x0000681C
+#define VMCS_GUEST_RIP 0x0000681E
+#define VMCS_GUEST_RFLAGS 0x00006820
+#define VMCS_GUEST_PENDING_DBG_EXCEPTIONS 0x00006822
+#define VMCS_GUEST_IA32_SYSENTER_ESP 0x00006824
+#define VMCS_GUEST_IA32_SYSENTER_EIP 0x00006826
/* Natural Width host-state fields */
-#define VMCS_HOST_CR0 0x00006C00
-#define VMCS_HOST_CR3 0x00006C02
-#define VMCS_HOST_CR4 0x00006C04
-#define VMCS_HOST_FS_BASE 0x00006C06
-#define VMCS_HOST_GS_BASE 0x00006C08
-#define VMCS_HOST_TR_BASE 0x00006C0A
-#define VMCS_HOST_GDTR_BASE 0x00006C0C
-#define VMCS_HOST_IDTR_BASE 0x00006C0E
-#define VMCS_HOST_IA32_SYSENTER_ESP 0x00006C10
-#define VMCS_HOST_IA32_SYSENTER_EIP 0x00006C12
-#define VMCS_HOST_RSP 0x00006C14
-#define VMCS_HOST_RIP 0x00006c16
+#define VMCS_HOST_CR0 0x00006C00
+#define VMCS_HOST_CR3 0x00006C02
+#define VMCS_HOST_CR4 0x00006C04
+#define VMCS_HOST_FS_BASE 0x00006C06
+#define VMCS_HOST_GS_BASE 0x00006C08
+#define VMCS_HOST_TR_BASE 0x00006C0A
+#define VMCS_HOST_GDTR_BASE 0x00006C0C
+#define VMCS_HOST_IDTR_BASE 0x00006C0E
+#define VMCS_HOST_IA32_SYSENTER_ESP 0x00006C10
+#define VMCS_HOST_IA32_SYSENTER_EIP 0x00006C12
+#define VMCS_HOST_RSP 0x00006C14
+#define VMCS_HOST_RIP 0x00006c16
/*
* VM instruction error numbers
*/
-#define VMRESUME_WITH_NON_LAUNCHED_VMCS 5
+#define VMRESUME_WITH_NON_LAUNCHED_VMCS 5
/*
* VMCS exit reasons
*/
-#define EXIT_REASON_EXCEPTION 0
-#define EXIT_REASON_EXT_INTR 1
-#define EXIT_REASON_TRIPLE_FAULT 2
-#define EXIT_REASON_INIT 3
-#define EXIT_REASON_SIPI 4
-#define EXIT_REASON_IO_SMI 5
-#define EXIT_REASON_SMI 6
-#define EXIT_REASON_INTR_WINDOW 7
-#define EXIT_REASON_NMI_WINDOW 8
-#define EXIT_REASON_TASK_SWITCH 9
-#define EXIT_REASON_CPUID 10
-#define EXIT_REASON_GETSEC 11
-#define EXIT_REASON_HLT 12
-#define EXIT_REASON_INVD 13
-#define EXIT_REASON_INVLPG 14
-#define EXIT_REASON_RDPMC 15
-#define EXIT_REASON_RDTSC 16
-#define EXIT_REASON_RSM 17
-#define EXIT_REASON_VMCALL 18
-#define EXIT_REASON_VMCLEAR 19
-#define EXIT_REASON_VMLAUNCH 20
-#define EXIT_REASON_VMPTRLD 21
-#define EXIT_REASON_VMPTRST 22
-#define EXIT_REASON_VMREAD 23
-#define EXIT_REASON_VMRESUME 24
-#define EXIT_REASON_VMWRITE 25
-#define EXIT_REASON_VMXOFF 26
-#define EXIT_REASON_VMXON 27
-#define EXIT_REASON_CR_ACCESS 28
-#define EXIT_REASON_DR_ACCESS 29
-#define EXIT_REASON_INOUT 30
-#define EXIT_REASON_RDMSR 31
-#define EXIT_REASON_WRMSR 32
-#define EXIT_REASON_INVAL_VMCS 33
-#define EXIT_REASON_INVAL_MSR 34
-#define EXIT_REASON_MWAIT 36
-#define EXIT_REASON_MTF 37
-#define EXIT_REASON_MONITOR 39
-#define EXIT_REASON_PAUSE 40
-#define EXIT_REASON_MCE_DURING_ENTRY 41
-#define EXIT_REASON_TPR 43
-#define EXIT_REASON_APIC_ACCESS 44
-#define EXIT_REASON_VIRTUALIZED_EOI 45
-#define EXIT_REASON_GDTR_IDTR 46
-#define EXIT_REASON_LDTR_TR 47
-#define EXIT_REASON_EPT_FAULT 48
-#define EXIT_REASON_EPT_MISCONFIG 49
-#define EXIT_REASON_INVEPT 50
-#define EXIT_REASON_RDTSCP 51
-#define EXIT_REASON_VMX_PREEMPT 52
-#define EXIT_REASON_INVVPID 53
-#define EXIT_REASON_WBINVD 54
-#define EXIT_REASON_XSETBV 55
-#define EXIT_REASON_APIC_WRITE 56
+#define EXIT_REASON_EXCEPTION 0
+#define EXIT_REASON_EXT_INTR 1
+#define EXIT_REASON_TRIPLE_FAULT 2
+#define EXIT_REASON_INIT 3
+#define EXIT_REASON_SIPI 4
+#define EXIT_REASON_IO_SMI 5
+#define EXIT_REASON_SMI 6
+#define EXIT_REASON_INTR_WINDOW 7
+#define EXIT_REASON_NMI_WINDOW 8
+#define EXIT_REASON_TASK_SWITCH 9
+#define EXIT_REASON_CPUID 10
+#define EXIT_REASON_GETSEC 11
+#define EXIT_REASON_HLT 12
+#define EXIT_REASON_INVD 13
+#define EXIT_REASON_INVLPG 14
+#define EXIT_REASON_RDPMC 15
+#define EXIT_REASON_RDTSC 16
+#define EXIT_REASON_RSM 17
+#define EXIT_REASON_VMCALL 18
+#define EXIT_REASON_VMCLEAR 19
+#define EXIT_REASON_VMLAUNCH 20
+#define EXIT_REASON_VMPTRLD 21
+#define EXIT_REASON_VMPTRST 22
+#define EXIT_REASON_VMREAD 23
+#define EXIT_REASON_VMRESUME 24
+#define EXIT_REASON_VMWRITE 25
+#define EXIT_REASON_VMXOFF 26
+#define EXIT_REASON_VMXON 27
+#define EXIT_REASON_CR_ACCESS 28
+#define EXIT_REASON_DR_ACCESS 29
+#define EXIT_REASON_INOUT 30
+#define EXIT_REASON_RDMSR 31
+#define EXIT_REASON_WRMSR 32
+#define EXIT_REASON_INVAL_VMCS 33
+#define EXIT_REASON_INVAL_MSR 34
+#define EXIT_REASON_MWAIT 36
+#define EXIT_REASON_MTF 37
+#define EXIT_REASON_MONITOR 39
+#define EXIT_REASON_PAUSE 40
+#define EXIT_REASON_MCE_DURING_ENTR 41
+#define EXIT_REASON_TPR 43
+#define EXIT_REASON_APIC_ACCESS 44
+#define EXIT_REASON_VIRTUALIZED_EOI 45
+#define EXIT_REASON_GDTR_IDTR 46
+#define EXIT_REASON_LDTR_TR 47
+#define EXIT_REASON_EPT_FAULT 48
+#define EXIT_REASON_EPT_MISCONFIG 49
+#define EXIT_REASON_INVEPT 50
+#define EXIT_REASON_RDTSCP 51
+#define EXIT_REASON_VMX_PREEMPT 52
+#define EXIT_REASON_INVVPID 53
+#define EXIT_REASON_WBINVD 54
+#define EXIT_REASON_XSETBV 55
+#define EXIT_REASON_APIC_WRITE 56
/*
* NMI unblocking due to IRET.
*
* Applies to VM-exits due to hardware exception or EPT fault.
*/
-#define EXIT_QUAL_NMIUDTI (1 << 12)
+#define EXIT_QUAL_NMIUDTI (1 << 12)
/*
* VMCS interrupt information fields
*/
-#define VMCS_INTR_VALID (1U << 31)
-#define VMCS_INTR_T_MASK 0x700 /* Interruption-info type */
-#define VMCS_INTR_T_HWINTR (0 << 8)
-#define VMCS_INTR_T_NMI (2 << 8)
-#define VMCS_INTR_T_HWEXCEPTION (3 << 8)
-#define VMCS_INTR_T_SWINTR (4 << 8)
-#define VMCS_INTR_T_PRIV_SWEXCEPTION (5 << 8)
-#define VMCS_INTR_T_SWEXCEPTION (6 << 8)
-#define VMCS_INTR_DEL_ERRCODE (1 << 11)
+#define VMCS_INTR_VALID (1U << 31)
+#define VMCS_INTR_T_MASK 0x700 /* Interruption-info type */
+#define VMCS_INTR_T_HWINTR (0 << 8)
+#define VMCS_INTR_T_NMI (2 << 8)
+#define VMCS_INTR_T_HWEXCEPTION (3 << 8)
+#define VMCS_INTR_T_SWINTR (4 << 8)
+#define VMCS_INTR_T_PRIV_SWEXCEPTION (5 << 8)
+#define VMCS_INTR_T_SWEXCEPTION (6 << 8)
+#define VMCS_INTR_DEL_ERRCODE (1 << 11)
/*
* VMCS IDT-Vectoring information fields
*/
-#define VMCS_IDT_VEC_VALID (1U << 31)
-#define VMCS_IDT_VEC_TYPE 0x700
-#define VMCS_IDT_VEC_ERRCODE_VALID (1U << 11)
-#define VMCS_IDT_VEC_HWINTR (0 << 8)
-#define VMCS_IDT_VEC_NMI (2 << 8)
-#define VMCS_IDT_VEC_HWEXCEPTION (3 << 8)
-#define VMCS_IDT_VEC_SWINTR (4 << 8)
+#define VMCS_IDT_VEC_VALID (1U << 31)
+#define VMCS_IDT_VEC_TYPE 0x700
+#define VMCS_IDT_VEC_ERRCODE_VALID (1U << 11)
+#define VMCS_IDT_VEC_HWINTR (0 << 8)
+#define VMCS_IDT_VEC_NMI (2 << 8)
+#define VMCS_IDT_VEC_HWEXCEPTION (3 << 8)
+#define VMCS_IDT_VEC_SWINTR (4 << 8)
/*
* VMCS Guest interruptibility field
*/
-#define VMCS_INTERRUPTIBILITY_STI_BLOCKING (1 << 0)
-#define VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING (1 << 1)
-#define VMCS_INTERRUPTIBILITY_SMI_BLOCKING (1 << 2)
-#define VMCS_INTERRUPTIBILITY_NMI_BLOCKING (1 << 3)
+#define VMCS_INTERRUPTIBILITY_STI_BLOCKING (1 << 0)
+#define VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING (1 << 1)
+#define VMCS_INTERRUPTIBILITY_SMI_BLOCKING (1 << 2)
+#define VMCS_INTERRUPTIBILITY_NMI_BLOCKING (1 << 3)
/*
* Exit qualification for EXIT_REASON_INVAL_VMCS
*/
-#define EXIT_QUAL_NMI_WHILE_STI_BLOCKING 3
+#define EXIT_QUAL_NMI_WHILE_STI_BLOCKING 3
/*
* Exit qualification for EPT violation
*/
-#define EPT_VIOLATION_DATA_READ (1UL << 0)
-#define EPT_VIOLATION_DATA_WRITE (1UL << 1)
-#define EPT_VIOLATION_INST_FETCH (1UL << 2)
-#define EPT_VIOLATION_GPA_READABLE (1UL << 3)
-#define EPT_VIOLATION_GPA_WRITEABLE (1UL << 4)
-#define EPT_VIOLATION_GPA_EXECUTABLE (1UL << 5)
-#define EPT_VIOLATION_GLA_VALID (1UL << 7)
-#define EPT_VIOLATION_XLAT_VALID (1UL << 8)
+#define EPT_VIOLATION_DATA_READ (1UL << 0)
+#define EPT_VIOLATION_DATA_WRITE (1UL << 1)
+#define EPT_VIOLATION_INST_FETCH (1UL << 2)
+#define EPT_VIOLATION_GPA_READABLE (1UL << 3)
+#define EPT_VIOLATION_GPA_WRITEABLE (1UL << 4)
+#define EPT_VIOLATION_GPA_EXECUTABLE (1UL << 5)
+#define EPT_VIOLATION_GLA_VALID (1UL << 7)
+#define EPT_VIOLATION_XLAT_VALID (1UL << 8)
/*
* Exit qualification for APIC-access VM exit
*/
-#define APIC_ACCESS_OFFSET(qual) ((qual) & 0xFFF)
-#define APIC_ACCESS_TYPE(qual) (((qual) >> 12) & 0xF)
+#define APIC_ACCESS_OFFSET(qual) ((qual) & 0xFFF)
+#define APIC_ACCESS_TYPE(qual) (((qual) >> 12) & 0xF)
/*
* Exit qualification for APIC-write VM exit
*/
-#define APIC_WRITE_OFFSET(qual) ((qual) & 0xFFF)
+#define APIC_WRITE_OFFSET(qual) ((qual) & 0xFFF)
-#define VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING (1 << 2)
-#define VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET (1 << 3)
-#define VMCS_PRI_PROC_BASED_CTLS_HLT (1 << 7)
+#define VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING (1 << 2)
+#define VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET (1 << 3)
+#define VMCS_PRI_PROC_BASED_CTLS_HLT (1 << 7)
#define VMCS_PRI_PROC_BASED_CTLS_MWAIT (1 << 10)
#define VMCS_PRI_PROC_BASED_CTLS_TSC (1 << 12)
#define VMCS_PRI_PROC_BASED_CTLS_CR8_LOAD (1 << 19)
@@ -359,10 +359,10 @@
#define VMCS_PRI_PROC_BASED2_CTLS_X2APIC (1 << 4)
enum task_switch_reason {
- TSR_CALL,
- TSR_IRET,
+ TSR_CALL,
+ TSR_IRET,
TSR_JMP,
- TSR_IDT_GATE, /* task gate in IDT */
+ TSR_IDT_GATE, /* task gate in IDT */
};
#endif
@@ -31,45 +31,45 @@
#include "exec/address-spaces.h"
-static uint64_t inline rreg(hv_vcpuid_t vcpu, hv_x86_reg_t reg)
+static inline uint64_t rreg(hv_vcpuid_t vcpu, hv_x86_reg_t reg)
{
- uint64_t v;
+ uint64_t v;
- if (hv_vcpu_read_register(vcpu, reg, &v)) {
- abort();
- }
+ if (hv_vcpu_read_register(vcpu, reg, &v)) {
+ abort();
+ }
- return v;
+ return v;
}
/* write GPR */
-static void inline wreg(hv_vcpuid_t vcpu, hv_x86_reg_t reg, uint64_t v)
+static inline void wreg(hv_vcpuid_t vcpu, hv_x86_reg_t reg, uint64_t v)
{
- if (hv_vcpu_write_register(vcpu, reg, v)) {
- abort();
- }
+ if (hv_vcpu_write_register(vcpu, reg, v)) {
+ abort();
+ }
}
/* read VMCS field */
-static uint64_t inline rvmcs(hv_vcpuid_t vcpu, uint32_t field)
+static inline uint64_t rvmcs(hv_vcpuid_t vcpu, uint32_t field)
{
- uint64_t v;
+ uint64_t v;
- hv_vmx_vcpu_read_vmcs(vcpu, field, &v);
+ hv_vmx_vcpu_read_vmcs(vcpu, field, &v);
- return v;
+ return v;
}
/* write VMCS field */
-static void inline wvmcs(hv_vcpuid_t vcpu, uint32_t field, uint64_t v)
+static inline void wvmcs(hv_vcpuid_t vcpu, uint32_t field, uint64_t v)
{
- hv_vmx_vcpu_write_vmcs(vcpu, field, v);
+ hv_vmx_vcpu_write_vmcs(vcpu, field, v);
}
/* desired control word constrained by hardware/hypervisor capabilities */
-static uint64_t inline cap2ctrl(uint64_t cap, uint64_t ctrl)
+static inline uint64_t cap2ctrl(uint64_t cap, uint64_t ctrl)
{
- return (ctrl | (cap & 0xffffffff)) & (cap >> 32);
+ return (ctrl | (cap & 0xffffffff)) & (cap >> 32);
}
#define VM_ENTRY_GUEST_LMA (1LL << 9)
@@ -91,11 +91,14 @@ static void enter_long_mode(hv_vcpuid_t vcpu, uint64_t cr0, uint64_t efer)
efer |= EFER_LMA;
wvmcs(vcpu, VMCS_GUEST_IA32_EFER, efer);
entry_ctls = rvmcs(vcpu, VMCS_ENTRY_CTLS);
- wvmcs(vcpu, VMCS_ENTRY_CTLS, rvmcs(vcpu, VMCS_ENTRY_CTLS) | VM_ENTRY_GUEST_LMA);
+ wvmcs(vcpu, VMCS_ENTRY_CTLS, rvmcs(vcpu, VMCS_ENTRY_CTLS) |
+ VM_ENTRY_GUEST_LMA);
uint64_t guest_tr_ar = rvmcs(vcpu, VMCS_GUEST_TR_ACCESS_RIGHTS);
- if ((efer & EFER_LME) && (guest_tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_64_TSS) {
- wvmcs(vcpu, VMCS_GUEST_TR_ACCESS_RIGHTS, (guest_tr_ar & ~AR_TYPE_MASK) | AR_TYPE_BUSY_64_TSS);
+ if ((efer & EFER_LME) &&
+ (guest_tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_64_TSS) {
+ wvmcs(vcpu, VMCS_GUEST_TR_ACCESS_RIGHTS,
+ (guest_tr_ar & ~AR_TYPE_MASK) | AR_TYPE_BUSY_64_TSS);
}
}
@@ -110,39 +113,45 @@ static void exit_long_mode(hv_vcpuid_t vcpu, uint64_t cr0, uint64_t efer)
wvmcs(vcpu, VMCS_GUEST_IA32_EFER, efer);
}
-static void inline macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
+static inline void macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
{
int i;
uint64_t pdpte[4] = {0, 0, 0, 0};
uint64_t efer = rvmcs(vcpu, VMCS_GUEST_IA32_EFER);
uint64_t old_cr0 = rvmcs(vcpu, VMCS_GUEST_CR0);
- if ((cr0 & CR0_PG) && (rvmcs(vcpu, VMCS_GUEST_CR4) & CR4_PAE) && !(efer & EFER_LME))
- address_space_rw(&address_space_memory, rvmcs(vcpu, VMCS_GUEST_CR3) & ~0x1f,
+ if ((cr0 & CR0_PG) && (rvmcs(vcpu, VMCS_GUEST_CR4) & CR4_PAE) &&
+ !(efer & EFER_LME)) {
+ address_space_rw(&address_space_memory,
+ rvmcs(vcpu, VMCS_GUEST_CR3) & ~0x1f,
MEMTXATTRS_UNSPECIFIED,
(uint8_t *)pdpte, 32, 0);
+ }
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++) {
wvmcs(vcpu, VMCS_GUEST_PDPTE0 + i * 2, pdpte[i]);
+ }
wvmcs(vcpu, VMCS_CR0_MASK, CR0_CD | CR0_NE | CR0_PG);
wvmcs(vcpu, VMCS_CR0_SHADOW, cr0);
cr0 &= ~CR0_CD;
- wvmcs(vcpu, VMCS_GUEST_CR0, cr0 | CR0_NE| CR0_ET);
+ wvmcs(vcpu, VMCS_GUEST_CR0, cr0 | CR0_NE | CR0_ET);
if (efer & EFER_LME) {
- if (!(old_cr0 & CR0_PG) && (cr0 & CR0_PG))
- enter_long_mode(vcpu, cr0, efer);
- if (/*(old_cr0 & CR0_PG) &&*/ !(cr0 & CR0_PG))
+ if (!(old_cr0 & CR0_PG) && (cr0 & CR0_PG)) {
+ enter_long_mode(vcpu, cr0, efer);
+ }
+ if (/*(old_cr0 & CR0_PG) &&*/ !(cr0 & CR0_PG)) {
exit_long_mode(vcpu, cr0, efer);
+ }
}
hv_vcpu_invalidate_tlb(vcpu);
hv_vcpu_flush(vcpu);
}
-static void inline macvm_set_cr4(hv_vcpuid_t vcpu, uint64_t cr4)
+static inline void macvm_set_cr4(hv_vcpuid_t vcpu, uint64_t cr4)
{
uint64_t guest_cr4 = cr4 | CR4_VMXE;
@@ -153,7 +162,7 @@ static void inline macvm_set_cr4(hv_vcpuid_t vcpu, uint64_t cr4)
hv_vcpu_flush(vcpu);
}
-static void inline macvm_set_rip(CPUState *cpu, uint64_t rip)
+static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
{
uint64_t val;
@@ -162,39 +171,44 @@ static void inline macvm_set_rip(CPUState *cpu, uint64_t rip)
/* after moving forward in rip, we need to clean INTERRUPTABILITY */
val = rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
- if (val & (VMCS_INTERRUPTIBILITY_STI_BLOCKING | VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING))
+ if (val & (VMCS_INTERRUPTIBILITY_STI_BLOCKING |
+ VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) {
wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY,
- val & ~(VMCS_INTERRUPTIBILITY_STI_BLOCKING | VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING));
+ val & ~(VMCS_INTERRUPTIBILITY_STI_BLOCKING |
+ VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING));
+ }
}
-static void inline vmx_clear_nmi_blocking(CPUState *cpu)
+static inline void vmx_clear_nmi_blocking(CPUState *cpu)
{
uint32_t gi = (uint32_t) rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
gi &= ~VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
}
-static void inline vmx_set_nmi_blocking(CPUState *cpu)
+static inline void vmx_set_nmi_blocking(CPUState *cpu)
{
uint32_t gi = (uint32_t)rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
gi |= VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
}
-static void inline vmx_set_nmi_window_exiting(CPUState *cpu)
+static inline void vmx_set_nmi_window_exiting(CPUState *cpu)
{
uint64_t val;
val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val | VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
+ wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val |
+ VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
}
-static void inline vmx_clear_nmi_window_exiting(CPUState *cpu)
+static inline void vmx_clear_nmi_window_exiting(CPUState *cpu)
{
uint64_t val;
val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val & ~VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
+ wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val &
+ ~VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
}
#endif
@@ -26,35 +26,38 @@
#include "x86_mmu.h"
#include "x86_descr.h"
-static uint32_t x86_segment_access_rights(struct x86_segment_descriptor *var)
+/* static uint32_t x86_segment_access_rights(struct x86_segment_descriptor *var)
{
- uint32_t ar;
-
- if (!var->p) {
- ar = 1 << 16;
- return ar;
- }
-
- ar = var->type & 15;
- ar |= (var->s & 1) << 4;
- ar |= (var->dpl & 3) << 5;
- ar |= (var->p & 1) << 7;
- ar |= (var->avl & 1) << 12;
- ar |= (var->l & 1) << 13;
- ar |= (var->db & 1) << 14;
- ar |= (var->g & 1) << 15;
- return ar;
-}
-
-bool x86_read_segment_descriptor(struct CPUState *cpu, struct x86_segment_descriptor *desc, x68_segment_selector sel)
+ uint32_t ar;
+
+ if (!var->p) {
+ ar = 1 << 16;
+ return ar;
+ }
+
+ ar = var->type & 15;
+ ar |= (var->s & 1) << 4;
+ ar |= (var->dpl & 3) << 5;
+ ar |= (var->p & 1) << 7;
+ ar |= (var->avl & 1) << 12;
+ ar |= (var->l & 1) << 13;
+ ar |= (var->db & 1) << 14;
+ ar |= (var->g & 1) << 15;
+ return ar;
+}*/
+
+bool x86_read_segment_descriptor(struct CPUState *cpu,
+ struct x86_segment_descriptor *desc,
+ x68_segment_selector sel)
{
addr_t base;
uint32_t limit;
ZERO_INIT(*desc);
- // valid gdt descriptors start from index 1
- if (!sel.index && GDT_SEL == sel.ti)
+ /* valid gdt descriptors start from index 1 */
+ if (!sel.index && GDT_SEL == sel.ti) {
return false;
+ }
if (GDT_SEL == sel.ti) {
base = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE);
@@ -64,18 +67,21 @@ bool x86_read_segment_descriptor(struct CPUState *cpu, struct x86_segment_descri
limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT);
}
- if (sel.index * 8 >= limit)
+ if (sel.index * 8 >= limit) {
return false;
+ }
vmx_read_mem(cpu, desc, base + sel.index * 8, sizeof(*desc));
return true;
}
-bool x86_write_segment_descriptor(struct CPUState *cpu, struct x86_segment_descriptor *desc, x68_segment_selector sel)
+bool x86_write_segment_descriptor(struct CPUState *cpu,
+ struct x86_segment_descriptor *desc,
+ x68_segment_selector sel)
{
addr_t base;
uint32_t limit;
-
+
if (GDT_SEL == sel.ti) {
base = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE);
limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
@@ -83,23 +89,24 @@ bool x86_write_segment_descriptor(struct CPUState *cpu, struct x86_segment_descr
base = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE);
limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT);
}
-
+
if (sel.index * 8 >= limit) {
- printf("%s: gdt limit\n", __FUNCTION__);
+ printf("%s: gdt limit\n", __func__);
return false;
}
vmx_write_mem(cpu, base + sel.index * 8, desc, sizeof(*desc));
return true;
}
-bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc, int gate)
+bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
+ int gate)
{
addr_t base = rvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_BASE);
uint32_t limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_LIMIT);
ZERO_INIT(*idt_desc);
if (gate * 8 >= limit) {
- printf("%s: idt limit\n", __FUNCTION__);
+ printf("%s: idt limit\n", __func__);
return false;
}
@@ -120,7 +127,7 @@ bool x86_is_real(struct CPUState *cpu)
bool x86_is_v8086(struct CPUState *cpu)
{
- return (x86_is_protected(cpu) && (RFLAGS(cpu) & RFLAGS_VM));
+ return x86_is_protected(cpu) && (RFLAGS(cpu) & RFLAGS_VM);
}
bool x86_is_long_mode(struct CPUState *cpu)
@@ -153,17 +160,18 @@ addr_t linear_addr(struct CPUState *cpu, addr_t addr, x86_reg_segment seg)
return vmx_read_segment_base(cpu, seg) + addr;
}
-addr_t linear_addr_size(struct CPUState *cpu, addr_t addr, int size, x86_reg_segment seg)
+addr_t linear_addr_size(struct CPUState *cpu, addr_t addr, int size,
+ x86_reg_segment seg)
{
switch (size) {
- case 2:
- addr = (uint16_t)addr;
- break;
- case 4:
- addr = (uint32_t)addr;
- break;
- default:
- break;
+ case 2:
+ addr = (uint16_t)addr;
+ break;
+ case 4:
+ addr = (uint32_t)addr;
+ break;
+ default:
+ break;
}
return linear_addr(cpu, addr, seg);
}
@@ -25,26 +25,26 @@
#include "qemu-common.h"
#include "x86_flags.h"
-// exceptions
+/* exceptions */
typedef enum x86_exception {
- EXCEPTION_DE, // divide error
- EXCEPTION_DB, // debug fault
- EXCEPTION_NMI, // non-maskable interrupt
- EXCEPTION_BP, // breakpoint trap
- EXCEPTION_OF, // overflow trap
- EXCEPTION_BR, // boundary range exceeded fault
- EXCEPTION_UD, // undefined opcode
- EXCEPTION_NM, // device not available
- EXCEPTION_DF, // double fault
- EXCEPTION_RSVD, // not defined
- EXCEPTION_TS, // invalid TSS fault
- EXCEPTION_NP, // not present fault
- EXCEPTION_GP, // general protection fault
- EXCEPTION_PF, // page fault
- EXCEPTION_RSVD2, // not defined
+ EXCEPTION_DE, /* divide error */
+ EXCEPTION_DB, /* debug fault */
+ EXCEPTION_NMI, /* non-maskable interrupt */
+ EXCEPTION_BP, /* breakpoint trap */
+ EXCEPTION_OF, /* overflow trap */
+ EXCEPTION_BR, /* boundary range exceeded fault */
+ EXCEPTION_UD, /* undefined opcode */
+ EXCEPTION_NM, /* device not available */
+ EXCEPTION_DF, /* double fault */
+ EXCEPTION_RSVD, /* not defined */
+ EXCEPTION_TS, /* invalid TSS fault */
+ EXCEPTION_NP, /* not present fault */
+ EXCEPTION_GP, /* general protection fault */
+ EXCEPTION_PF, /* page fault */
+ EXCEPTION_RSVD2, /* not defined */
} x86_exception;
-// general purpose regs
+/* general purpose regs */
typedef enum x86_reg_name {
REG_RAX = 0,
REG_RCX = 1,
@@ -64,7 +64,7 @@ typedef enum x86_reg_name {
REG_R15 = 15,
} x86_reg_name;
-// segment regs
+/* segment regs */
typedef enum x86_reg_segment {
REG_SEG_ES = 0,
REG_SEG_CS = 1,
@@ -76,24 +76,23 @@ typedef enum x86_reg_segment {
REG_SEG_TR = 7,
} x86_reg_segment;
-typedef struct x86_register
-{
+typedef struct x86_register {
union {
struct {
- uint64_t rrx; // full 64 bit
+ uint64_t rrx; /* full 64 bit */
};
struct {
- uint32_t erx; // low 32 bit part
+ uint32_t erx; /* low 32 bit part */
uint32_t hi32_unused1;
};
struct {
- uint16_t rx; // low 16 bit part
+ 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
+ uint8_t lx; /* low 8 bit part */
+ uint8_t hx; /* high 8 bit */
uint16_t hi16_unused2;
uint32_t hi32_unused3;
};
@@ -120,7 +119,7 @@ typedef enum x86_rflags {
RFLAGS_ID = (1L << 21),
} x86_rflags;
-// rflags register
+/* rflags register */
typedef struct x86_reg_flags {
union {
struct {
@@ -205,7 +204,7 @@ typedef enum x86_reg_cr4 {
CR4_SMEP = (1L << 20),
} x86_reg_cr4;
-// 16 bit Task State Segment
+/* 16 bit Task State Segment */
typedef struct x86_tss_segment16 {
uint16_t link;
uint16_t sp0;
@@ -231,9 +230,8 @@ typedef struct x86_tss_segment16 {
uint16_t ldtr;
} __attribute__((packed)) x86_tss_segment16;
-// 32 bit Task State Segment
-typedef struct x86_tss_segment32
-{
+/* 32 bit Task State Segment */
+typedef struct x86_tss_segment32 {
uint32_t prev_tss;
uint32_t esp0;
uint32_t ss0;
@@ -263,9 +261,8 @@ typedef struct x86_tss_segment32
uint16_t iomap_base;
} __attribute__ ((__packed__)) x86_tss_segment32;
-// 64 bit Task State Segment
-typedef struct x86_tss_segment64
-{
+/* 64 bit Task State Segment */
+typedef struct x86_tss_segment64 {
uint32_t unused;
uint64_t rsp0;
uint64_t rsp1;
@@ -283,7 +280,7 @@ typedef struct x86_tss_segment64
uint16_t iomap_base;
} __attribute__ ((__packed__)) x86_tss_segment64;
-// segment descriptors
+/* segment descriptors */
typedef struct x86_segment_descriptor {
uint64_t limit0:16;
uint64_t base0:16;
@@ -305,7 +302,8 @@ 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)
+static inline void x86_set_segment_base(x86_segment_descriptor *desc,
+ uint32_t base)
{
desc->base2 = base >> 24;
desc->base1 = (base >> 16) & 0xff;
@@ -315,12 +313,14 @@ static inline void x86_set_segment_base(x86_segment_descriptor *desc, uint32_t b
static inline uint32_t x86_segment_limit(x86_segment_descriptor *desc)
{
uint32_t limit = (uint32_t)((desc->limit1 << 16) | desc->limit0);
- if (desc->g)
+ if (desc->g) {
return (limit << 12) | 0xfff;
+ }
return limit;
}
-static inline void x86_set_segment_limit(x86_segment_descriptor *desc, uint32_t limit)
+static inline void x86_set_segment_limit(x86_segment_descriptor *desc,
+ uint32_t limit)
{
desc->limit0 = limit & 0xffff;
desc->limit1 = limit >> 16;
@@ -356,11 +356,11 @@ typedef struct x68_segment_selector {
};
} __attribute__ ((__packed__)) x68_segment_selector;
-// Definition of hvf_x86_state is here
+/* Definition of hvf_x86_state is here */
struct hvf_x86_state {
int hlt;
uint64_t init_tsc;
-
+
int interruptable;
uint64_t exp_rip;
uint64_t fetch_rip;
@@ -370,7 +370,7 @@ struct hvf_x86_state {
struct lazy_flags lflags;
struct x86_efer efer;
uint8_t mmio_buf[4096];
- uint8_t* apic_page;
+ uint8_t *apic_page;
};
/*
@@ -380,7 +380,7 @@ struct hvf_xsave_buf {
uint32_t data[1024];
};
-// useful register access macros
+/* useful register access macros */
#define RIP(cpu) (cpu->hvf_x86->rip)
#define EIP(cpu) ((uint32_t)cpu->hvf_x86->rip)
#define RFLAGS(cpu) (cpu->hvf_x86->rflags.rflags)
@@ -436,13 +436,18 @@ struct hvf_xsave_buf {
#define DH(cpu) RH(cpu, REG_RDX)
#define BH(cpu) RH(cpu, REG_RBX)
-// deal with GDT/LDT descriptors in memory
-bool x86_read_segment_descriptor(struct CPUState *cpu, struct x86_segment_descriptor *desc, x68_segment_selector sel);
-bool x86_write_segment_descriptor(struct CPUState *cpu, struct x86_segment_descriptor *desc, x68_segment_selector sel);
+/* deal with GDT/LDT descriptors in memory */
+bool x86_read_segment_descriptor(struct CPUState *cpu,
+ struct x86_segment_descriptor *desc,
+ x68_segment_selector sel);
+bool x86_write_segment_descriptor(struct CPUState *cpu,
+ struct x86_segment_descriptor *desc,
+ x68_segment_selector sel);
-bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc, int gate);
+bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
+ int gate);
-// helpers
+/* helpers */
bool x86_is_protected(struct CPUState *cpu);
bool x86_is_real(struct CPUState *cpu);
bool x86_is_v8086(struct CPUState *cpu);
@@ -452,19 +457,20 @@ bool x86_is_paging_mode(struct CPUState *cpu);
bool x86_is_pae_enabled(struct CPUState *cpu);
addr_t linear_addr(struct CPUState *cpu, addr_t addr, x86_reg_segment seg);
-addr_t linear_addr_size(struct CPUState *cpu, addr_t addr, int size, x86_reg_segment seg);
+addr_t linear_addr_size(struct CPUState *cpu, addr_t addr, int size,
+ x86_reg_segment seg);
addr_t linear_rip(struct CPUState *cpu, addr_t 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
+ __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
-
+ : "%rcx", "%rdx"); /* rcx and rdx are clobbered */
+
return tsc;
}
@@ -41,10 +41,10 @@ struct x86_cpuid builtin_cpus[] = {
.model = 3,
.stepping = 3,
.features = PPRO_FEATURES,
- .ext_features = /*CPUID_EXT_SSE3 |*/ CPUID_EXT_POPCNT, CPUID_MTRR | CPUID_CLFLUSH,
- CPUID_PSE36,
+ .ext_features = /*CPUID_EXT_SSE3 |*/ CPUID_EXT_POPCNT, CPUID_MTRR |
+ CPUID_CLFLUSH, CPUID_PSE36,
.ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
- .ext3_features = 0,//CPUID_EXT3_LAHF_LM,
+ .ext3_features = 0, /* CPUID_EXT3_LAHF_LM, */
.xlevel = 0x80000004,
.model_id = "vmx32",
},
@@ -92,14 +92,15 @@ struct x86_cpuid builtin_cpus[] = {
},
};
-static struct x86_cpuid *_cpuid = NULL;
+static struct x86_cpuid *_cpuid;
-void init_cpuid(struct CPUState* cpu)
+void init_cpuid(struct CPUState *cpu)
{
- _cpuid = &builtin_cpus[2]; // core2duo
+ _cpuid = &builtin_cpus[2]; /* core2duo */
}
-void get_cpuid_func(struct CPUState* cpu, int func, int cnt, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
+void get_cpuid_func(struct CPUState *cpu, int func, int cnt, uint32_t *eax,
+ uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
{
uint32_t h_rax, h_rbx, h_rcx, h_rdx;
host_cpuid(func, cnt, &h_rax, &h_rbx, &h_rcx, &h_rdx);
@@ -107,164 +108,172 @@ void get_cpuid_func(struct CPUState* cpu, int func, int cnt, uint32_t *eax, uint
*eax = *ebx = *ecx = *edx = 0;
- switch(func) {
- case 0:
- *eax = _cpuid->level;
- *ebx = _cpuid->vendor1;
- *edx = _cpuid->vendor2;
- *ecx = _cpuid->vendor3;
- break;
- case 1:
- *eax = h_rax;//_cpuid->stepping | (_cpuid->model << 3) | (_cpuid->family << 6);
- *ebx = (apic_id << 24) | (h_rbx & 0x00ffffff);
- *ecx = h_rcx;
- *edx = h_rdx;
+ switch (func) {
+ case 0:
+ *eax = _cpuid->level;
+ *ebx = _cpuid->vendor1;
+ *edx = _cpuid->vendor2;
+ *ecx = _cpuid->vendor3;
+ break;
+ case 1:
+ *eax = h_rax;/*_cpuid->stepping | (_cpuid->model << 3) |
+ (_cpuid->family << 6); */
+ *ebx = (apic_id << 24) | (h_rbx & 0x00ffffff);
+ *ecx = h_rcx;
+ *edx = h_rdx;
- if (cpu->nr_cores * cpu->nr_threads > 1) {
- *ebx |= (cpu->nr_cores * cpu->nr_threads) << 16;
- *edx |= 1 << 28; /* Enable Hyper-Threading */
- }
+ if (cpu->nr_cores * cpu->nr_threads > 1) {
+ *ebx |= (cpu->nr_cores * cpu->nr_threads) << 16;
+ *edx |= 1 << 28; /* Enable Hyper-Threading */
+ }
- *ecx = *ecx & ~(CPUID_EXT_OSXSAVE | CPUID_EXT_MONITOR | CPUID_EXT_X2APIC |
- CPUID_EXT_VMX | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_TM2 | CPUID_EXT_PCID |
- CPUID_EXT_EST | CPUID_EXT_SSE42 | CPUID_EXT_SSE41);
- *ecx |= CPUID_EXT_HYPERVISOR;
- break;
- case 2:
- /* cache info: needed for Pentium Pro compatibility */
- *eax = h_rax;
- *ebx = h_rbx;
- *ecx = h_rcx;
- *edx = h_rdx;
- break;
- case 4:
- /* cache info: needed for Core compatibility */
- *eax = h_rax;
- *ebx = h_rbx;
- *ecx = h_rcx;
- *edx = h_rdx;
- break;
- case 5:
- /* mwait info: needed for Core compatibility */
- *eax = h_rax;
- *ebx = h_rbx;
- *ecx = h_rcx;
- *edx = h_rdx;
- break;
- case 6:
- /* Thermal and Power Leaf */
- *eax = 0;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
- break;
- case 7:
- *eax = h_rax;
- *ebx = h_rbx & ~(CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512PF | CPUID_7_0_EBX_AVX512ER | CPUID_7_0_EBX_AVX512CD |
- CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_INVPCID);
- *ecx = h_rcx & ~(CPUID_7_0_ECX_AVX512BMI);
- *edx = h_rdx;
- break;
- case 9:
- /* Direct Cache Access Information Leaf */
- *eax = h_rax;
- *ebx = h_rbx;
- *ecx = h_rcx;
- *edx = h_rdx;
- break;
- case 0xA:
- /* Architectural Performance Monitoring Leaf */
- *eax = 0;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
- break;
- case 0xB:
- /* CPU Topology Leaf */
- *eax = 0;
- *ebx = 0; /* Means that we don't support this leaf */
- *ecx = 0;
- *edx = 0;
- break;
- case 0xD:
- *eax = h_rax;
- if (!cnt)
- *eax &= (XSTATE_FP_MASK | XSTATE_SSE_MASK | XSTATE_YMM_MASK);
- if (1 == cnt)
- *eax &= (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC);
- *ebx = h_rbx;
- *ecx = h_rcx;
- *edx = h_rdx;
- break;
- case 0x80000000:
- *eax = _cpuid->xlevel;
- *ebx = _cpuid->vendor1;
- *edx = _cpuid->vendor2;
- *ecx = _cpuid->vendor3;
- break;
- case 0x80000001:
- *eax = h_rax;//_cpuid->stepping | (_cpuid->model << 3) | (_cpuid->family << 6);
- *ebx = 0;
- *ecx = _cpuid->ext3_features & h_rcx;
- *edx = _cpuid->ext2_features & h_rdx;
- break;
- case 0x80000002:
- case 0x80000003:
- case 0x80000004:
- *eax = h_rax;
- *ebx = h_rbx;
- *ecx = h_rcx;
- *edx = h_rdx;
- break;
- case 0x80000005:
- /* cache info (L1 cache) */
- *eax = h_rax;
- *ebx = h_rbx;
- *ecx = h_rcx;
- *edx = h_rdx;
- break;
- case 0x80000006:
- /* cache info (L2 cache) */
- *eax = h_rax;
- *ebx = h_rbx;
- *ecx = h_rcx;
- *edx = h_rdx;
- break;
- case 0x80000007:
- *eax = 0;
- *ebx = 0;
- *ecx = 0;
- *edx = 0; /* Note - We disable invariant TSC (bit 8) in purpose */
- break;
- case 0x80000008:
- /* virtual & phys address size in low 2 bytes. */
- *eax = h_rax;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
- break;
- case 0x8000000A:
- *eax = 0;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
- break;
- case 0x80000019:
- *eax = h_rax;
- *ebx = h_rbx;
- *ecx = 0;
- *edx = 0;
- case 0xC0000000:
- *eax = _cpuid->xlevel2;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
- break;
- default:
- *eax = 0;
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
- break;
+ *ecx = *ecx & ~(CPUID_EXT_OSXSAVE | CPUID_EXT_MONITOR |
+ CPUID_EXT_X2APIC | CPUID_EXT_VMX |
+ CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_TM2 |
+ CPUID_EXT_PCID | CPUID_EXT_EST | CPUID_EXT_SSE42 |
+ CPUID_EXT_SSE41);
+ *ecx |= CPUID_EXT_HYPERVISOR;
+ break;
+ case 2:
+ /* cache info: needed for Pentium Pro compatibility */
+ *eax = h_rax;
+ *ebx = h_rbx;
+ *ecx = h_rcx;
+ *edx = h_rdx;
+ break;
+ case 4:
+ /* cache info: needed for Core compatibility */
+ *eax = h_rax;
+ *ebx = h_rbx;
+ *ecx = h_rcx;
+ *edx = h_rdx;
+ break;
+ case 5:
+ /* mwait info: needed for Core compatibility */
+ *eax = h_rax;
+ *ebx = h_rbx;
+ *ecx = h_rcx;
+ *edx = h_rdx;
+ break;
+ case 6:
+ /* Thermal and Power Leaf */
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 7:
+ *eax = h_rax;
+ *ebx = h_rbx & ~(CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512PF |
+ CPUID_7_0_EBX_AVX512ER | CPUID_7_0_EBX_AVX512CD |
+ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL |
+ CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_INVPCID);
+ *ecx = h_rcx & ~(CPUID_7_0_ECX_AVX512BMI);
+ *edx = h_rdx;
+ break;
+ case 9:
+ /* Direct Cache Access Information Leaf */
+ *eax = h_rax;
+ *ebx = h_rbx;
+ *ecx = h_rcx;
+ *edx = h_rdx;
+ break;
+ case 0xA:
+ /* Architectural Performance Monitoring Leaf */
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 0xB:
+ /* CPU Topology Leaf */
+ *eax = 0;
+ *ebx = 0; /* Means that we don't support this leaf */
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 0xD:
+ *eax = h_rax;
+ if (!cnt) {
+ *eax &= (XSTATE_FP_MASK | XSTATE_SSE_MASK | XSTATE_YMM_MASK);
+ }
+ if (1 == cnt) {
+ *eax &= (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC);
+ }
+ *ebx = h_rbx;
+ *ecx = h_rcx;
+ *edx = h_rdx;
+ break;
+ case 0x80000000:
+ *eax = _cpuid->xlevel;
+ *ebx = _cpuid->vendor1;
+ *edx = _cpuid->vendor2;
+ *ecx = _cpuid->vendor3;
+ break;
+ case 0x80000001:
+ *eax = h_rax;/*_cpuid->stepping | (_cpuid->model << 3) |
+ (_cpuid->family << 6);*/
+ *ebx = 0;
+ *ecx = _cpuid->ext3_features & h_rcx;
+ *edx = _cpuid->ext2_features & h_rdx;
+ break;
+ case 0x80000002:
+ case 0x80000003:
+ case 0x80000004:
+ *eax = h_rax;
+ *ebx = h_rbx;
+ *ecx = h_rcx;
+ *edx = h_rdx;
+ break;
+ case 0x80000005:
+ /* cache info (L1 cache) */
+ *eax = h_rax;
+ *ebx = h_rbx;
+ *ecx = h_rcx;
+ *edx = h_rdx;
+ break;
+ case 0x80000006:
+ /* cache info (L2 cache) */
+ *eax = h_rax;
+ *ebx = h_rbx;
+ *ecx = h_rcx;
+ *edx = h_rdx;
+ break;
+ case 0x80000007:
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0; /* Note - We disable invariant TSC (bit 8) in purpose */
+ break;
+ case 0x80000008:
+ /* virtual & phys address size in low 2 bytes. */
+ *eax = h_rax;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 0x8000000A:
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ case 0x80000019:
+ *eax = h_rax;
+ *ebx = h_rbx;
+ *ecx = 0;
+ *edx = 0;
+ case 0xC0000000:
+ *eax = _cpuid->xlevel2;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
+ default:
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ break;
}
}
@@ -35,7 +35,7 @@ struct x86_cpuid {
uint32_t features, ext_features, ext2_features, ext3_features;
uint32_t kvm_features, svm_features;
uint32_t xlevel;
- char model_id[48];
+ char model_id[50];
int vendor_override;
uint32_t flags;
uint32_t xlevel2;
@@ -44,8 +44,9 @@ struct x86_cpuid {
struct CPUState;
-void init_cpuid(struct CPUState* cpu);
-void get_cpuid_func(struct CPUState *cpu, int func, int cnt, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
+void init_cpuid(struct CPUState *cpu);
+void get_cpuid_func(struct CPUState *cpu, int func, int cnt, uint32_t *eax,
+ uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
#endif /* __CPUID_H__ */
@@ -29,9 +29,11 @@
static void decode_invalid(CPUState *cpu, struct x86_decode *decode)
{
- printf("%llx: failed to decode instruction ", cpu->hvf_x86->fetch_rip - decode->len);
- for (int i = 0; i < decode->opcode_len; i++)
+ printf("%llx: failed to decode instruction ", cpu->hvf_x86->fetch_rip -
+ decode->len);
+ for (int i = 0; i < decode->opcode_len; i++) {
printf("%x ", decode->opcode[i]);
+ }
printf("\n");
VM_PANIC("decoder failed\n");
}
@@ -39,43 +41,44 @@ static void decode_invalid(CPUState *cpu, struct x86_decode *decode)
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", __FUNCTION__, size);
- break;
+ 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(CPUState *cpu, struct x86_decode *decode, int size)
+static inline uint64_t decode_bytes(CPUState *cpu, struct x86_decode *decode,
+ int size)
{
addr_t val = 0;
-
+
switch (size) {
- case 1:
- case 2:
- case 4:
- case 8:
- break;
- default:
- VM_PANIC_EX("%s invalid size %d\n", __FUNCTION__, size);
- break;
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ break;
+ default:
+ VM_PANIC_EX("%s invalid size %d\n", __func__, size);
+ break;
}
addr_t va = linear_rip(cpu, RIP(cpu)) + decode->len;
vmx_read_mem(cpu, &val, va, size);
decode->len += size;
-
+
return val;
}
@@ -99,68 +102,76 @@ static inline uint64_t decode_qword(CPUState *cpu, struct x86_decode *decode)
return decode_bytes(cpu, decode, 8);
}
-static void decode_modrm_rm(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_modrm_rm(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X86_VAR_RM;
}
-static void decode_modrm_reg(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_modrm_reg(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X86_VAR_REG;
op->reg = decode->modrm.reg;
op->ptr = get_reg_ref(cpu, op->reg, decode->rex.r, decode->operand_size);
}
-static void decode_rax(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_rax(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X86_VAR_REG;
op->reg = REG_RAX;
op->ptr = get_reg_ref(cpu, op->reg, 0, decode->operand_size);
}
-static inline void decode_immediate(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *var, int size)
+static inline void decode_immediate(CPUState *cpu, 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(cpu, decode);
- break;
- case 2:
- var->val = decode_word(cpu, decode);
- break;
- case 4:
- var->val = decode_dword(cpu, decode);
- break;
- case 8:
- var->val = decode_qword(cpu, decode);
- break;
- default:
- VM_PANIC_EX("bad size %d\n", size);
+ case 1:
+ var->val = decode_byte(cpu, decode);
+ break;
+ case 2:
+ var->val = decode_word(cpu, decode);
+ break;
+ case 4:
+ var->val = decode_dword(cpu, decode);
+ break;
+ case 8:
+ var->val = decode_qword(cpu, decode);
+ break;
+ default:
+ VM_PANIC_EX("bad size %d\n", size);
}
}
-static void decode_imm8(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_imm8(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
decode_immediate(cpu, decode, op, 1);
op->type = X86_VAR_IMMEDIATE;
}
-static void decode_imm8_signed(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_imm8_signed(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
decode_immediate(cpu, decode, op, 1);
op->val = sign(op->val, 1);
op->type = X86_VAR_IMMEDIATE;
}
-static void decode_imm16(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_imm16(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
decode_immediate(cpu, decode, op, 2);
op->type = X86_VAR_IMMEDIATE;
}
-static void decode_imm(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_imm(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
if (8 == decode->operand_size) {
decode_immediate(cpu, decode, op, 4);
@@ -171,20 +182,23 @@ static void decode_imm(CPUState *cpu, struct x86_decode *decode, struct x86_deco
op->type = X86_VAR_IMMEDIATE;
}
-static void decode_imm_signed(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_imm_signed(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
decode_immediate(cpu, decode, op, decode->operand_size);
op->val = sign(op->val, decode->operand_size);
op->type = X86_VAR_IMMEDIATE;
}
-static void decode_imm_1(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_imm_1(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X86_VAR_IMMEDIATE;
op->val = 1;
}
-static void decode_imm_0(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_imm_0(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X86_VAR_IMMEDIATE;
op->val = 0;
@@ -194,54 +208,54 @@ static void decode_imm_0(CPUState *cpu, struct x86_decode *decode, struct x86_de
static void decode_pushseg(CPUState *cpu, 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 = REG_SEG_CS;
- break;
- case 0x16:
- decode->op[0].reg = REG_SEG_SS;
- break;
- case 0x1e:
- decode->op[0].reg = REG_SEG_DS;
- break;
- case 0x06:
- decode->op[0].reg = REG_SEG_ES;
- break;
- case 0xa0:
- decode->op[0].reg = REG_SEG_FS;
- break;
- case 0xa8:
- decode->op[0].reg = REG_SEG_GS;
- break;
+ case 0xe:
+ decode->op[0].reg = REG_SEG_CS;
+ break;
+ case 0x16:
+ decode->op[0].reg = REG_SEG_SS;
+ break;
+ case 0x1e:
+ decode->op[0].reg = REG_SEG_DS;
+ break;
+ case 0x06:
+ decode->op[0].reg = REG_SEG_ES;
+ break;
+ case 0xa0:
+ decode->op[0].reg = REG_SEG_FS;
+ break;
+ case 0xa8:
+ decode->op[0].reg = REG_SEG_GS;
+ break;
}
}
static void decode_popseg(CPUState *cpu, 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 = REG_SEG_CS;
- break;
- case 0x17:
- decode->op[0].reg = REG_SEG_SS;
- break;
- case 0x1f:
- decode->op[0].reg = REG_SEG_DS;
- break;
- case 0x07:
- decode->op[0].reg = REG_SEG_ES;
- break;
- case 0xa1:
- decode->op[0].reg = REG_SEG_FS;
- break;
- case 0xa9:
- decode->op[0].reg = REG_SEG_GS;
- break;
+ case 0xf:
+ decode->op[0].reg = REG_SEG_CS;
+ break;
+ case 0x17:
+ decode->op[0].reg = REG_SEG_SS;
+ break;
+ case 0x1f:
+ decode->op[0].reg = REG_SEG_DS;
+ break;
+ case 0x07:
+ decode->op[0].reg = REG_SEG_ES;
+ break;
+ case 0xa1:
+ decode->op[0].reg = REG_SEG_FS;
+ break;
+ case 0xa9:
+ decode->op[0].reg = REG_SEG_GS;
+ break;
}
}
@@ -249,36 +263,41 @@ static void decode_incgroup(CPUState *cpu, 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(cpu, decode->op[0].reg, decode->rex.b, decode->operand_size);
+ decode->op[0].ptr = get_reg_ref(cpu, decode->op[0].reg, decode->rex.b,
+ decode->operand_size);
}
static void decode_decgroup(CPUState *cpu, 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(cpu, decode->op[0].reg, decode->rex.b, decode->operand_size);
+ decode->op[0].ptr = get_reg_ref(cpu, decode->op[0].reg, decode->rex.b,
+ decode->operand_size);
}
static void decode_incgroup2(CPUState *cpu, struct x86_decode *decode)
{
- if (!decode->modrm.reg)
+ if (!decode->modrm.reg) {
decode->cmd = X86_DECODE_CMD_INC;
- else if (1 == decode->modrm.reg)
+ } else if (1 == decode->modrm.reg) {
decode->cmd = X86_DECODE_CMD_DEC;
+ }
}
static void decode_pushgroup(CPUState *cpu, 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(cpu, decode->op[0].reg, decode->rex.b, decode->operand_size);
+ decode->op[0].ptr = get_reg_ref(cpu, decode->op[0].reg, decode->rex.b,
+ decode->operand_size);
}
static void decode_popgroup(CPUState *cpu, 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(cpu, decode->op[0].reg, decode->rex.b, decode->operand_size);
+ decode->op[0].ptr = get_reg_ref(cpu, decode->op[0].reg, decode->rex.b,
+ decode->operand_size);
}
static void decode_jxx(CPUState *cpu, struct x86_decode *decode)
@@ -340,18 +359,18 @@ static void decode_f7group(CPUState *cpu, struct x86_decode *decode)
decode_modrm_rm(cpu, decode, &decode->op[0]);
switch (decode->modrm.reg) {
- case 0:
- case 1:
- decode_imm(cpu, 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;
+ case 0:
+ case 1:
+ decode_imm(cpu, 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;
}
}
@@ -359,18 +378,21 @@ static void decode_xchgroup(CPUState *cpu, 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(cpu, decode->op[0].reg, decode->rex.b, decode->operand_size);
+ decode->op[0].ptr = get_reg_ref(cpu, decode->op[0].reg, decode->rex.b,
+ decode->operand_size);
}
static void decode_movgroup(CPUState *cpu, 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(cpu, decode->op[0].reg, decode->rex.b, decode->operand_size);
+ decode->op[0].ptr = get_reg_ref(cpu, decode->op[0].reg, decode->rex.b,
+ decode->operand_size);
decode_immediate(cpu, decode, &decode->op[1], decode->operand_size);
}
-static void fetch_moffs(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void fetch_moffs(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X86_VAR_OFFSET;
op->ptr = decode_bytes(cpu, decode, decode->addressing_size);
@@ -380,11 +402,13 @@ static void decode_movgroup8(CPUState *cpu, 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(cpu, decode->op[0].reg, decode->rex.b, decode->operand_size);
+ decode->op[0].ptr = get_reg_ref(cpu, decode->op[0].reg, decode->rex.b,
+ decode->operand_size);
decode_immediate(cpu, decode, &decode->op[1], decode->operand_size);
}
-static void decode_rcx(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_rcx(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X86_VAR_REG;
op->reg = REG_RCX;
@@ -396,10 +420,14 @@ struct decode_tbl {
enum x86_decode_cmd cmd;
uint8_t operand_size;
bool is_modrm;
- void (*decode_op1)(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op1);
- void (*decode_op2)(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op2);
- void (*decode_op3)(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op3);
- void (*decode_op4)(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op4);
+ void (*decode_op1)(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op1);
+ void (*decode_op2)(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op2);
+ void (*decode_op3)(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op3);
+ void (*decode_op4)(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op4);
void (*decode_postfix)(CPUState *cpu, struct x86_decode *decode);
addr_t flags_mask;
};
@@ -412,13 +440,16 @@ struct decode_x87_tbl {
uint8_t operand_size;
bool rev;
bool pop;
- void (*decode_op1)(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op1);
- void (*decode_op2)(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op2);
+ void (*decode_op1)(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op1);
+ void (*decode_op2)(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op2);
void (*decode_postfix)(CPUState *cpu, struct x86_decode *decode);
addr_t flags_mask;
};
-struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL, decode_invalid};
+struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL,
+ decode_invalid};
struct decode_tbl _decode_tbl1[255];
struct decode_tbl _decode_tbl2[255];
@@ -427,28 +458,35 @@ struct decode_x87_tbl _decode_tbl3[255];
static void decode_x87_ins(CPUState *cpu, 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;
-
+ int index = ((decode->opcode[0] & 0xf) << 4) | (mode << 3) |
+ decode->modrm.reg;
+
decoder = &_decode_tbl3[index];
-
+
decode->cmd = decoder->cmd;
- if (decoder->operand_size)
+ 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)
+
+ if (decoder->decode_op1) {
decoder->decode_op1(cpu, decode, &decode->op[0]);
- if (decoder->decode_op2)
+ }
+ if (decoder->decode_op2) {
decoder->decode_op2(cpu, decode, &decode->op[1]);
- if (decoder->decode_postfix)
+ }
+ if (decoder->decode_postfix) {
decoder->decode_postfix(cpu, 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);
+ }
+
+ 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(CPUState *cpu, struct x86_decode *decode)
@@ -465,8 +503,9 @@ static void decode_ffgroup(CPUState *cpu, struct x86_decode *decode)
X86_DECODE_CMD_INVL
};
decode->cmd = group[decode->modrm.reg];
- if (decode->modrm.reg > 2)
+ if (decode->modrm.reg > 2) {
decode->flags_mask = 0;
+ }
}
static void decode_sldtgroup(CPUState *cpu, struct x86_decode *decode)
@@ -482,7 +521,8 @@ static void decode_sldtgroup(CPUState *cpu, struct x86_decode *decode)
X86_DECODE_CMD_INVL
};
decode->cmd = group[decode->modrm.reg];
- printf("%llx: decode_sldtgroup: %d\n", cpu->hvf_x86->fetch_rip, decode->modrm.reg);
+ printf("%llx: decode_sldtgroup: %d\n", cpu->hvf_x86->fetch_rip,
+ decode->modrm.reg);
}
static void decode_lidtgroup(CPUState *cpu, struct x86_decode *decode)
@@ -524,28 +564,34 @@ static void decode_x87_general(CPUState *cpu, struct x86_decode *decode)
decode->is_fpu = true;
}
-static void decode_x87_modrm_floatp(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_x87_modrm_floatp(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X87_VAR_FLOATP;
}
-static void decode_x87_modrm_intp(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_x87_modrm_intp(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X87_VAR_INTP;
}
-static void decode_x87_modrm_bytep(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_x87_modrm_bytep(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X87_VAR_BYTEP;
}
-static void decode_x87_modrm_st0(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_x87_modrm_st0(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X87_VAR_REG;
op->reg = 0;
}
-static void decode_decode_x87_modrm_st0(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+static void decode_decode_x87_modrm_st0(CPUState *cpu,
+ struct x86_decode *decode,
+ struct x86_decode_op *op)
{
op->type = X87_VAR_REG;
op->reg = decode->modrm.modrm & 7;
@@ -556,35 +602,35 @@ static void decode_aegroup(CPUState *cpu, struct x86_decode *decode)
{
decode->is_fpu = true;
switch (decode->modrm.reg) {
- case 0:
- decode->cmd = X86_DECODE_CMD_FXSAVE;
- decode_x87_modrm_bytep(cpu, decode, &decode->op[0]);
- break;
- case 1:
- decode_x87_modrm_bytep(cpu, 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_ON_EX(1, "0xae: reg %d\n", decode->modrm.reg);
- break;
+ case 0:
+ decode->cmd = X86_DECODE_CMD_FXSAVE;
+ decode_x87_modrm_bytep(cpu, decode, &decode->op[0]);
+ break;
+ case 1:
+ decode_x87_modrm_bytep(cpu, 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_ON_EX(1, "0xae: reg %d\n", decode->modrm.reg);
+ break;
}
}
@@ -592,568 +638,1003 @@ static void decode_bswap(CPUState *cpu, 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(cpu, decode->op[0].reg, decode->rex.b, decode->operand_size);
+ decode->op[0].ptr = get_reg_ref(cpu, decode->op[0].reg, decode->rex.b,
+ decode->operand_size);
}
static void decode_d9_4(CPUState *cpu, 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_ON_EX(1, "FTST");
- break;
- case 0xe5:
- // FXAM
- decode->cmd = X86_DECODE_CMD_FXAM;
- break;
- default:
- VM_PANIC_ON_EX(1, "FLDENV");
- break;
+ 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_ON_EX(1, "FTST");
+ break;
+ case 0xe5:
+ /* FXAM */
+ decode->cmd = X86_DECODE_CMD_FXAM;
+ break;
+ default:
+ VM_PANIC_ON_EX(1, "FLDENV");
+ break;
}
}
static void decode_db_4(CPUState *cpu, struct x86_decode *decode)
{
switch (decode->modrm.modrm) {
- case 0xe0:
- VM_PANIC_ON_EX(1, "unhandled FNENI: %x %x\n", decode->opcode[0], decode->modrm.modrm);
- break;
- case 0xe1:
- VM_PANIC_ON_EX(1, "unhandled FNDISI: %x %x\n", decode->opcode[0], decode->modrm.modrm);
- break;
- case 0xe2:
- VM_PANIC_ON_EX(1, "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_ON_EX(1, "unhandled fpu opcode: %x %x\n", decode->opcode[0], decode->modrm.modrm);
- break;
+ case 0xe0:
+ VM_PANIC_ON_EX(1, "unhandled FNENI: %x %x\n", decode->opcode[0],
+ decode->modrm.modrm);
+ break;
+ case 0xe1:
+ VM_PANIC_ON_EX(1, "unhandled FNDISI: %x %x\n", decode->opcode[0],
+ decode->modrm.modrm);
+ break;
+ case 0xe2:
+ VM_PANIC_ON_EX(1, "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_ON_EX(1, "unhandled fpu opcode: %x %x\n", decode->opcode[0],
+ decode->modrm.modrm);
+ break;
}
}
#define RFLAGS_MASK_NONE 0
-#define RFLAGS_MASK_OSZAPC (RFLAGS_OF | RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | RFLAGS_PF | RFLAGS_CF)
-#define RFLAGS_MASK_LAHF (RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | RFLAGS_PF | RFLAGS_CF)
+#define RFLAGS_MASK_OSZAPC (RFLAGS_OF | RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | \
+ RFLAGS_PF | RFLAGS_CF)
+#define RFLAGS_MASK_LAHF (RFLAGS_SF | RFLAGS_ZF | RFLAGS_AF | RFLAGS_PF | \
+ RFLAGS_CF)
#define RFLAGS_MASK_CF (RFLAGS_CF)
#define RFLAGS_MASK_IF (RFLAGS_IF)
#define RFLAGS_MASK_TF (RFLAGS_TF)
#define RFLAGS_MASK_DF (RFLAGS_DF)
#define RFLAGS_MASK_ZF (RFLAGS_ZF)
-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 _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_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},
+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(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+void calc_modrm_operand16(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
addr_t ptr = 0;
x86_reg_segment seg = REG_SEG_DS;
@@ -1163,43 +1644,45 @@ void calc_modrm_operand16(CPUState *cpu, struct x86_decode *decode, struct x86_d
goto calc_addr;
}
- if (decode->displacement_size)
+ if (decode->displacement_size) {
ptr = sign(decode->displacement, decode->displacement_size);
+ }
switch (decode->modrm.rm) {
- case 0:
- ptr += BX(cpu) + SI(cpu);
- break;
- case 1:
- ptr += BX(cpu) + DI(cpu);
- break;
- case 2:
- ptr += BP(cpu) + SI(cpu);
- seg = REG_SEG_SS;
- break;
- case 3:
- ptr += BP(cpu) + DI(cpu);
- seg = REG_SEG_SS;
- break;
- case 4:
- ptr += SI(cpu);
- break;
- case 5:
- ptr += DI(cpu);
- break;
- case 6:
- ptr += BP(cpu);
- seg = REG_SEG_SS;
- break;
- case 7:
- ptr += BX(cpu);
- break;
+ case 0:
+ ptr += BX(cpu) + SI(cpu);
+ break;
+ case 1:
+ ptr += BX(cpu) + DI(cpu);
+ break;
+ case 2:
+ ptr += BP(cpu) + SI(cpu);
+ seg = REG_SEG_SS;
+ break;
+ case 3:
+ ptr += BP(cpu) + DI(cpu);
+ seg = REG_SEG_SS;
+ break;
+ case 4:
+ ptr += SI(cpu);
+ break;
+ case 5:
+ ptr += DI(cpu);
+ break;
+ case 6:
+ ptr += BP(cpu);
+ seg = REG_SEG_SS;
+ break;
+ case 7:
+ ptr += BX(cpu);
+ break;
}
calc_addr:
- if (X86_DECODE_CMD_LEA == decode->cmd)
+ if (X86_DECODE_CMD_LEA == decode->cmd) {
op->ptr = (uint16_t)ptr;
- else
+ } else {
op->ptr = decode_linear_addr(cpu, decode, (uint16_t)ptr, seg);
+ }
}
addr_t get_reg_ref(CPUState *cpu, int reg, int is_extended, int size)
@@ -1207,24 +1690,25 @@ addr_t get_reg_ref(CPUState *cpu, int reg, int is_extended, int size)
addr_t ptr = 0;
int which = 0;
- if (is_extended)
+ if (is_extended) {
reg |= REG_R8;
+ }
switch (size) {
- case 1:
- if (is_extended || reg < 4) {
- which = 1;
- ptr = (addr_t)&RL(cpu, reg);
- } else {
- which = 2;
- ptr = (addr_t)&RH(cpu, reg - 4);
- }
- break;
- default:
- which = 3;
- ptr = (addr_t)&RRX(cpu, reg);
- break;
+ case 1:
+ if (is_extended || reg < 4) {
+ which = 1;
+ ptr = (addr_t)&RL(cpu, reg);
+ } else {
+ which = 2;
+ ptr = (addr_t)&RH(cpu, reg - 4);
+ }
+ break;
+ default:
+ which = 3;
+ ptr = (addr_t)&RRX(cpu, reg);
+ break;
}
return ptr;
}
@@ -1232,11 +1716,12 @@ addr_t get_reg_ref(CPUState *cpu, int reg, int is_extended, int size)
addr_t get_reg_val(CPUState *cpu, int reg, int is_extended, int size)
{
addr_t val = 0;
- memcpy(&val, (void*)get_reg_ref(cpu, reg, is_extended, size), size);
+ memcpy(&val, (void *)get_reg_ref(cpu, reg, is_extended, size), size);
return val;
}
-static addr_t get_sib_val(CPUState *cpu, struct x86_decode *decode, x86_reg_segment *sel)
+static addr_t get_sib_val(CPUState *cpu, struct x86_decode *decode,
+ x86_reg_segment *sel)
{
addr_t base = 0;
addr_t scaled_index = 0;
@@ -1247,52 +1732,61 @@ static addr_t get_sib_val(CPUState *cpu, struct x86_decode *decode, x86_reg_segm
*sel = REG_SEG_DS;
if (decode->modrm.mod || base_reg != REG_RBP) {
- if (decode->rex.b)
+ if (decode->rex.b) {
base_reg |= REG_R8;
- if (REG_RSP == base_reg || REG_RBP == base_reg)
+ }
+ if (REG_RSP == base_reg || REG_RBP == base_reg) {
*sel = REG_SEG_SS;
+ }
base = get_reg_val(cpu, decode->sib.base, decode->rex.b, addr_size);
}
- if (decode->rex.x)
+ if (decode->rex.x) {
index_reg |= REG_R8;
+ }
- if (index_reg != REG_RSP)
- scaled_index = get_reg_val(cpu, index_reg, decode->rex.x, addr_size) << decode->sib.scale;
+ if (index_reg != REG_RSP) {
+ scaled_index = get_reg_val(cpu, index_reg, decode->rex.x, addr_size) <<
+ decode->sib.scale;
+ }
return base + scaled_index;
}
-void calc_modrm_operand32(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+void calc_modrm_operand32(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
x86_reg_segment seg = REG_SEG_DS;
addr_t ptr = 0;
int addr_size = decode->addressing_size;
- if (decode->displacement_size)
+ if (decode->displacement_size) {
ptr = sign(decode->displacement, decode->displacement_size);
+ }
if (4 == decode->modrm.rm) {
ptr += get_sib_val(cpu, decode, &seg);
- }
- else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
- if (x86_is_long_mode(cpu))
+ } else if (!decode->modrm.mod && 5 == decode->modrm.rm) {
+ if (x86_is_long_mode(cpu)) {
ptr += RIP(cpu) + decode->len;
- else
+ } else {
ptr = decode->displacement;
- }
- else {
- if (REG_RBP == decode->modrm.rm || REG_RSP == decode->modrm.rm)
+ }
+ } else {
+ if (REG_RBP == decode->modrm.rm || REG_RSP == decode->modrm.rm) {
seg = REG_SEG_SS;
+ }
ptr += get_reg_val(cpu, decode->modrm.rm, decode->rex.b, addr_size);
}
- if (X86_DECODE_CMD_LEA == decode->cmd)
+ if (X86_DECODE_CMD_LEA == decode->cmd) {
op->ptr = (uint32_t)ptr;
- else
+ } else {
op->ptr = decode_linear_addr(cpu, decode, (uint32_t)ptr, seg);
+ }
}
-void calc_modrm_operand64(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+void calc_modrm_operand64(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op)
{
x86_reg_segment seg = REG_SEG_DS;
int32_t offset = 0;
@@ -1300,46 +1794,51 @@ void calc_modrm_operand64(CPUState *cpu, struct x86_decode *decode, struct x86_d
int rm = decode->modrm.rm;
addr_t ptr;
int src = decode->modrm.rm;
-
- if (decode->displacement_size)
+
+ if (decode->displacement_size) {
offset = sign(decode->displacement, decode->displacement_size);
+ }
- if (4 == rm)
+ if (4 == rm) {
ptr = get_sib_val(cpu, decode, &seg) + offset;
- else if (0 == mod && 5 == rm)
+ } else if (0 == mod && 5 == rm) {
ptr = RIP(cpu) + decode->len + (int32_t) offset;
- else
+ } else {
ptr = get_reg_val(cpu, src, decode->rex.b, 8) + (int64_t) offset;
-
- if (X86_DECODE_CMD_LEA == decode->cmd)
+ }
+
+ if (X86_DECODE_CMD_LEA == decode->cmd) {
op->ptr = ptr;
- else
+ } else {
op->ptr = decode_linear_addr(cpu, decode, ptr, seg);
+ }
}
-void calc_modrm_operand(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op)
+void calc_modrm_operand(CPUState *cpu, 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(cpu, decode->modrm.rm, decode->rex.b, decode->operand_size);
+ op->ptr = get_reg_ref(cpu, decode->modrm.rm, decode->rex.b,
+ decode->operand_size);
return;
}
switch (decode->addressing_size) {
- case 2:
- calc_modrm_operand16(cpu, decode, op);
- break;
- case 4:
- calc_modrm_operand32(cpu, decode, op);
- break;
- case 8:
- calc_modrm_operand64(cpu, decode, op);
- break;
- default:
- VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size);
- break;
+ case 2:
+ calc_modrm_operand16(cpu, decode, op);
+ break;
+ case 4:
+ calc_modrm_operand32(cpu, decode, op);
+ break;
+ case 8:
+ calc_modrm_operand64(cpu, decode, op);
+ break;
+ default:
+ VM_PANIC_EX("unsupported address size %d\n", decode->addressing_size);
+ break;
}
}
@@ -1348,36 +1847,36 @@ static void decode_prefix(CPUState *cpu, struct x86_decode *decode)
while (1) {
uint8_t byte = decode_byte(cpu, decode);
switch (byte) {
- case PREFIX_LOCK:
- decode->lock = byte;
- break;
- case PREFIX_REPN:
- case PREFIX_REP:
- decode->rep = byte;
- break;
- case PREFIX_CS_SEG_OVEERIDE:
- case PREFIX_SS_SEG_OVEERIDE:
- case PREFIX_DS_SEG_OVEERIDE:
- case PREFIX_ES_SEG_OVEERIDE:
- case PREFIX_FS_SEG_OVEERIDE:
- case PREFIX_GS_SEG_OVEERIDE:
- decode->segment_override = byte;
- break;
- case PREFIX_OP_SIZE_OVERRIDE:
- decode->op_size_override = byte;
- break;
- case PREFIX_ADDR_SIZE_OVERRIDE:
- decode->addr_size_override = byte;
+ case PREFIX_LOCK:
+ decode->lock = byte;
+ break;
+ case PREFIX_REPN:
+ case PREFIX_REP:
+ decode->rep = byte;
+ break;
+ case PREFIX_CS_SEG_OVEERIDE:
+ case PREFIX_SS_SEG_OVEERIDE:
+ case PREFIX_DS_SEG_OVEERIDE:
+ case PREFIX_ES_SEG_OVEERIDE:
+ case PREFIX_FS_SEG_OVEERIDE:
+ case PREFIX_GS_SEG_OVEERIDE:
+ decode->segment_override = byte;
+ break;
+ case PREFIX_OP_SIZE_OVERRIDE:
+ decode->op_size_override = byte;
+ break;
+ case PREFIX_ADDR_SIZE_OVERRIDE:
+ decode->addr_size_override = byte;
+ break;
+ case PREFIX_REX ... (PREFIX_REX + 0xf):
+ if (x86_is_long_mode(cpu)) {
+ decode->rex.rex = byte;
break;
- case PREFIX_REX ... (PREFIX_REX + 0xf):
- if (x86_is_long_mode(cpu)) {
- decode->rex.rex = byte;
- break;
- }
- // fall through when not in long mode
- default:
- decode->len--;
- return;
+ }
+ /* fall through when not in long mode */
+ default:
+ decode->len--;
+ return;
}
}
}
@@ -1386,33 +1885,36 @@ void set_addressing_size(CPUState *cpu, struct x86_decode *decode)
{
decode->addressing_size = -1;
if (x86_is_real(cpu) || x86_is_v8086(cpu)) {
- if (decode->addr_size_override)
+ if (decode->addr_size_override) {
decode->addressing_size = 4;
- else
+ } else {
decode->addressing_size = 2;
- }
- else if (!x86_is_long_mode(cpu)) {
- // protected
+ }
+ } else if (!x86_is_long_mode(cpu)) {
+ /* protected */
struct vmx_segment cs;
vmx_read_segment_descriptor(cpu, &cs, REG_SEG_CS);
- // check db
+ /* check db */
if ((cs.ar >> 14) & 1) {
- if (decode->addr_size_override)
+ if (decode->addr_size_override) {
decode->addressing_size = 2;
- else
+ } else {
decode->addressing_size = 4;
+ }
} else {
- if (decode->addr_size_override)
+ if (decode->addr_size_override) {
decode->addressing_size = 4;
- else
+ } else {
decode->addressing_size = 2;
+ }
}
} else {
- // long
- if (decode->addr_size_override)
+ /* long */
+ if (decode->addr_size_override) {
decode->addressing_size = 4;
- else
+ } else {
decode->addressing_size = 8;
+ }
}
}
@@ -1420,99 +1922,98 @@ void set_operand_size(CPUState *cpu, struct x86_decode *decode)
{
decode->operand_size = -1;
if (x86_is_real(cpu) || x86_is_v8086(cpu)) {
- if (decode->op_size_override)
+ if (decode->op_size_override) {
decode->operand_size = 4;
- else
+ } else {
decode->operand_size = 2;
- }
- else if (!x86_is_long_mode(cpu)) {
- // protected
+ }
+ } else if (!x86_is_long_mode(cpu)) {
+ /* protected */
struct vmx_segment cs;
vmx_read_segment_descriptor(cpu, &cs, REG_SEG_CS);
- // check db
+ /* check db */
if ((cs.ar >> 14) & 1) {
- if (decode->op_size_override)
+ if (decode->op_size_override) {
decode->operand_size = 2;
- else
+ } else{
decode->operand_size = 4;
+ }
} else {
- if (decode->op_size_override)
+ if (decode->op_size_override) {
decode->operand_size = 4;
- else
+ } else {
decode->operand_size = 2;
+ }
}
} else {
- // long
- if (decode->op_size_override)
+ /* long */
+ if (decode->op_size_override) {
decode->operand_size = 2;
- else
+ } else {
decode->operand_size = 4;
+ }
- if (decode->rex.w)
+ if (decode->rex.w) {
decode->operand_size = 8;
+ }
}
}
static void decode_sib(CPUState *cpu, struct x86_decode *decode)
{
- if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) && (decode->addressing_size != 2)) {
+ if ((decode->modrm.mod != 3) && (4 == decode->modrm.rm) &&
+ (decode->addressing_size != 2)) {
decode->sib.sib = decode_byte(cpu, decode);
decode->sib_present = true;
}
}
-/* 16 bit modrm
- * mod R/M
- * 00 [BX+SI] [BX+DI] [BP+SI] [BP+DI] [SI] [DI] [disp16] [BX]
- * 01 [BX+SI+disp8] [BX+DI+disp8] [BP+SI+disp8] [BP+DI+disp8] [SI+disp8] [DI+disp8] [BP+disp8] [BX+disp8]
- * 10 [BX+SI+disp16] [BX+DI+disp16] [BP+SI+disp16] [BP+DI+disp16] [SI+disp16] [DI+disp16] [BP+disp16] [BX+disp16]
- * 11 - - - - - - - -
- */
-int disp16_tbl[4][8] =
- {{0, 0, 0, 0, 0, 0, 2, 0},
+/* 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}};
+ {0, 0, 0, 0, 0, 0, 0, 0}
+};
-/*
- 32/64-bit modrm
- Mod
- 00 [r/m] [r/m] [r/m] [r/m] [SIB] [RIP/EIP1,2+disp32] [r/m] [r/m]
- 01 [r/m+disp8] [r/m+disp8] [r/m+disp8] [r/m+disp8] [SIB+disp8] [r/m+disp8] [SIB+disp8] [r/m+disp8]
- 10 [r/m+disp32] [r/m+disp32] [r/m+disp32] [r/m+disp32] [SIB+disp32] [r/m+disp32] [SIB+disp32] [r/m+disp32]
- 11 - - - - - - - -
- */
-int disp32_tbl[4][8] =
- {{0, 0, 0, 0, -1, 4, 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}};
+ {0, 0, 0, 0, 0, 0, 0, 0}
+};
static inline void decode_displacement(CPUState *cpu, 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(cpu, decode, decode->displacement_size);
- break;
- case 4:
- case 8:
- if (-1 == disp32_tbl[mod][rm]) {
- if (5 == decode->sib.base)
- decode->displacement_size = 4;
+ case 2:
+ decode->displacement_size = disp16_tbl[mod][rm];
+ if (decode->displacement_size) {
+ decode->displacement = (uint16_t)decode_bytes(cpu, 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(cpu, decode, decode->displacement_size);
- break;
+ } else {
+ decode->displacement_size = disp32_tbl[mod][rm];
+ }
+
+ if (decode->displacement_size) {
+ decode->displacement = (uint32_t)decode_bytes(cpu, decode,
+ decode->displacement_size);
+ }
+ break;
}
}
@@ -1520,40 +2021,52 @@ static inline void decode_modrm(CPUState *cpu, struct x86_decode *decode)
{
decode->modrm.modrm = decode_byte(cpu, decode);
decode->is_modrm = true;
-
+
decode_sib(cpu, decode);
decode_displacement(cpu, decode);
}
-static inline void decode_opcode_general(CPUState *cpu, struct x86_decode *decode, uint8_t opcode, struct decode_tbl *inst_decoder)
+static inline void decode_opcode_general(CPUState *cpu,
+ struct x86_decode *decode,
+ uint8_t opcode,
+ struct decode_tbl *inst_decoder)
{
decode->cmd = inst_decoder->cmd;
- if (inst_decoder->operand_size)
+ if (inst_decoder->operand_size) {
decode->operand_size = inst_decoder->operand_size;
+ }
decode->flags_mask = inst_decoder->flags_mask;
-
- if (inst_decoder->is_modrm)
+
+ if (inst_decoder->is_modrm) {
decode_modrm(cpu, decode);
- if (inst_decoder->decode_op1)
+ }
+ if (inst_decoder->decode_op1) {
inst_decoder->decode_op1(cpu, decode, &decode->op[0]);
- if (inst_decoder->decode_op2)
+ }
+ if (inst_decoder->decode_op2) {
inst_decoder->decode_op2(cpu, decode, &decode->op[1]);
- if (inst_decoder->decode_op3)
+ }
+ if (inst_decoder->decode_op3) {
inst_decoder->decode_op3(cpu, decode, &decode->op[2]);
- if (inst_decoder->decode_op4)
+ }
+ if (inst_decoder->decode_op4) {
inst_decoder->decode_op4(cpu, decode, &decode->op[3]);
- if (inst_decoder->decode_postfix)
+ }
+ if (inst_decoder->decode_postfix) {
inst_decoder->decode_postfix(cpu, decode);
+ }
}
-static inline void decode_opcode_1(CPUState *cpu, struct x86_decode *decode, uint8_t opcode)
+static inline void decode_opcode_1(CPUState *cpu, struct x86_decode *decode,
+ uint8_t opcode)
{
struct decode_tbl *inst_decoder = &_decode_tbl1[opcode];
decode_opcode_general(cpu, decode, opcode, inst_decoder);
}
-static inline void decode_opcode_2(CPUState *cpu, struct x86_decode *decode, uint8_t opcode)
+static inline void decode_opcode_2(CPUState *cpu, struct x86_decode *decode,
+ uint8_t opcode)
{
struct decode_tbl *inst_decoder = &_decode_tbl2[opcode];
decode_opcode_general(cpu, decode, opcode, inst_decoder);
@@ -1562,7 +2075,7 @@ static inline void decode_opcode_2(CPUState *cpu, struct x86_decode *decode, uin
static void decode_opcodes(CPUState *cpu, struct x86_decode *decode)
{
uint8_t opcode;
-
+
opcode = decode_byte(cpu, decode);
decode->opcode[decode->opcode_len++] = opcode;
if (opcode != OPCODE_ESCAPE) {
@@ -1583,21 +2096,24 @@ uint32_t decode_instruction(CPUState *cpu, struct x86_decode *decode)
set_operand_size(cpu, decode);
decode_opcodes(cpu, decode);
-
+
return decode->len;
}
void init_decoder(CPUState *cpu)
{
int i;
-
- for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++)
+
+ for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
memcpy(_decode_tbl1, &invl_inst, sizeof(invl_inst));
- for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++)
+ }
+ for (i = 0; i < ARRAY_SIZE(_decode_tbl2); i++) {
memcpy(_decode_tbl2, &invl_inst, sizeof(invl_inst));
- for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++)
+ }
+ for (i = 0; i < ARRAY_SIZE(_decode_tbl3); i++) {
memcpy(_decode_tbl3, &invl_inst, sizeof(invl_inst_x87));
-
+ }
+
for (i = 0; i < ARRAY_SIZE(_1op_inst); i++) {
_decode_tbl1[_1op_inst[i].opcode] = _1op_inst[i];
}
@@ -1605,7 +2121,9 @@ void init_decoder(CPUState *cpu)
_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;
+ 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];
}
}
@@ -1613,47 +2131,55 @@ void init_decoder(CPUState *cpu)
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",
+ 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];
}
-addr_t decode_linear_addr(struct CPUState *cpu, struct x86_decode *decode, addr_t addr, x86_reg_segment seg)
+addr_t decode_linear_addr(struct CPUState *cpu, struct x86_decode *decode,
+ addr_t addr, x86_reg_segment seg)
{
switch (decode->segment_override) {
- case PREFIX_CS_SEG_OVEERIDE:
- seg = REG_SEG_CS;
- break;
- case PREFIX_SS_SEG_OVEERIDE:
- seg = REG_SEG_SS;
- break;
- case PREFIX_DS_SEG_OVEERIDE:
- seg = REG_SEG_DS;
- break;
- case PREFIX_ES_SEG_OVEERIDE:
- seg = REG_SEG_ES;
- break;
- case PREFIX_FS_SEG_OVEERIDE:
- seg = REG_SEG_FS;
- break;
- case PREFIX_GS_SEG_OVEERIDE:
- seg = REG_SEG_GS;
- break;
- default:
- break;
+ case PREFIX_CS_SEG_OVEERIDE:
+ seg = REG_SEG_CS;
+ break;
+ case PREFIX_SS_SEG_OVEERIDE:
+ seg = REG_SEG_SS;
+ break;
+ case PREFIX_DS_SEG_OVEERIDE:
+ seg = REG_SEG_DS;
+ break;
+ case PREFIX_ES_SEG_OVEERIDE:
+ seg = REG_SEG_ES;
+ break;
+ case PREFIX_FS_SEG_OVEERIDE:
+ seg = REG_SEG_FS;
+ break;
+ case PREFIX_GS_SEG_OVEERIDE:
+ seg = REG_SEG_GS;
+ break;
+ default:
+ break;
}
return linear_addr_size(cpu, addr, decode->addressing_size, seg);
}
@@ -25,20 +25,20 @@
#include "x86.h"
typedef enum x86_prefix {
- // group 1
+ /* group 1 */
PREFIX_LOCK = 0xf0,
PREFIX_REPN = 0xf2,
PREFIX_REP = 0xf3,
- // group 2
+ /* group 2 */
PREFIX_CS_SEG_OVEERIDE = 0x2e,
PREFIX_SS_SEG_OVEERIDE = 0x36,
PREFIX_DS_SEG_OVEERIDE = 0x3e,
PREFIX_ES_SEG_OVEERIDE = 0x26,
PREFIX_FS_SEG_OVEERIDE = 0x64,
PREFIX_GS_SEG_OVEERIDE = 0x65,
- // group 3
+ /* group 3 */
PREFIX_OP_SIZE_OVERRIDE = 0x66,
- // group 4
+ /* group 4 */
PREFIX_ADDR_SIZE_OVERRIDE = 0x67,
PREFIX_REX = 0x40,
@@ -46,7 +46,7 @@ typedef enum x86_prefix {
enum x86_decode_cmd {
X86_DECODE_CMD_INVL = 0,
-
+
X86_DECODE_CMD_PUSH,
X86_DECODE_CMD_PUSH_SEG,
X86_DECODE_CMD_POP,
@@ -177,7 +177,7 @@ enum x86_decode_cmd {
X86_DECODE_CMD_CMPXCHG8B,
X86_DECODE_CMD_CMPXCHG,
X86_DECODE_CMD_POPCNT,
-
+
X86_DECODE_CMD_FNINIT,
X86_DECODE_CMD_FLD,
X86_DECODE_CMD_FLDxx,
@@ -255,7 +255,7 @@ typedef enum x86_var_type {
X86_VAR_REG,
X86_VAR_RM,
- // for floating point computations
+ /* for floating point computations */
X87_VAR_REG,
X87_VAR_FLOATP,
X87_VAR_INTP,
@@ -308,7 +308,17 @@ uint32_t decode_instruction(CPUState *cpu, struct x86_decode *decode);
addr_t get_reg_ref(CPUState *cpu, int reg, int is_extended, int size);
addr_t get_reg_val(CPUState *cpu, int reg, int is_extended, int size);
-void calc_modrm_operand(CPUState *cpu, struct x86_decode *decode, struct x86_decode_op *op);
-addr_t decode_linear_addr(struct CPUState *cpu, struct x86_decode *decode, addr_t addr, x86_reg_segment seg);
+void calc_modrm_operand(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op);
+addr_t decode_linear_addr(struct CPUState *cpu, struct x86_decode *decode,
+ addr_t addr, x86_reg_segment seg);
-void init_decoder(CPUState* cpu);
+void init_decoder(CPUState *cpu);
+void calc_modrm_operand16(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op);
+void calc_modrm_operand32(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op);
+void calc_modrm_operand64(CPUState *cpu, struct x86_decode *decode,
+ struct x86_decode_op *op);
+void set_addressing_size(CPUState *cpu, struct x86_decode *decode);
+void set_operand_size(CPUState *cpu, struct x86_decode *decode);
@@ -27,14 +27,29 @@ typedef struct vmx_segment {
uint64_t ar;
} vmx_segment;
-// deal with vmstate descriptors
-void vmx_read_segment_descriptor(struct CPUState *cpu, struct vmx_segment *desc, x86_reg_segment seg);
-void vmx_write_segment_descriptor(CPUState *cpu, struct vmx_segment *desc, x86_reg_segment seg);
+/* deal with vmstate descriptors */
+void vmx_read_segment_descriptor(struct CPUState *cpu,
+ struct vmx_segment *desc, x86_reg_segment seg);
+void vmx_write_segment_descriptor(CPUState *cpu, struct vmx_segment *desc,
+ x86_reg_segment seg);
-x68_segment_selector vmx_read_segment_selector(struct CPUState *cpu, x86_reg_segment seg);
-void vmx_write_segment_selector(struct CPUState *cpu, x68_segment_selector selector, x86_reg_segment seg);
+x68_segment_selector vmx_read_segment_selector(struct CPUState *cpu,
+ x86_reg_segment seg);
+void vmx_write_segment_selector(struct CPUState *cpu,
+ x68_segment_selector selector,
+ x86_reg_segment seg);
uint64_t vmx_read_segment_base(struct CPUState *cpu, x86_reg_segment seg);
-void vmx_write_segment_base(struct CPUState *cpu, x86_reg_segment seg, uint64_t base);
+void vmx_write_segment_base(struct CPUState *cpu, x86_reg_segment seg,
+ uint64_t base);
-void x86_segment_descriptor_to_vmx(struct CPUState *cpu, x68_segment_selector selector, struct x86_segment_descriptor *desc, struct vmx_segment *vmx_desc);
+void x86_segment_descriptor_to_vmx(struct CPUState *cpu,
+ x68_segment_selector selector,
+ struct x86_segment_descriptor *desc,
+ struct vmx_segment *vmx_desc);
+
+uint32_t vmx_read_segment_limit(CPUState *cpu, x86_reg_segment seg);
+uint32_t vmx_read_segment_ar(CPUState *cpu, x86_reg_segment seg);
+void vmx_segment_to_x86_descriptor(struct CPUState *cpu,
+ struct vmx_segment *vmx_desc,
+ struct x86_segment_descriptor *desc);
@@ -45,8 +45,8 @@
#include "vmcs.h"
#include "vmx.h"
-static void print_debug(struct CPUState *cpu);
-void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int direction, int size, uint32_t count);
+void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data,
+ int direction, int size, uint32_t count);
#define EXEC_2OP_LOGIC_CMD(cpu, decode, cmd, FLAGS_FUNC, save_res) \
{ \
@@ -57,8 +57,9 @@ void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int directio
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) \
+ if (save_res) { \
write_val_ext(cpu, decode->op[0].ptr, diff, 1); \
+ } \
FLAGS_FUNC##_8(diff); \
break; \
} \
@@ -67,8 +68,9 @@ void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int directio
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) \
+ if (save_res) { \
write_val_ext(cpu, decode->op[0].ptr, diff, 2); \
+ } \
FLAGS_FUNC##_16(diff); \
break; \
} \
@@ -77,8 +79,9 @@ void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int directio
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) \
+ if (save_res) { \
write_val_ext(cpu, decode->op[0].ptr, diff, 4); \
+ } \
FLAGS_FUNC##_32(diff); \
break; \
} \
@@ -97,8 +100,9 @@ void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int directio
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) \
+ if (save_res) { \
write_val_ext(cpu, decode->op[0].ptr, diff, 1); \
+ } \
FLAGS_FUNC##_8(v1, v2, diff); \
break; \
} \
@@ -107,8 +111,9 @@ void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int directio
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) \
+ if (save_res) { \
write_val_ext(cpu, decode->op[0].ptr, diff, 2); \
+ } \
FLAGS_FUNC##_16(v1, v2, diff); \
break; \
} \
@@ -117,8 +122,9 @@ void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int directio
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) \
+ if (save_res) { \
write_val_ext(cpu, decode->op[0].ptr, diff, 4); \
+ } \
FLAGS_FUNC##_32(v1, v2, diff); \
break; \
} \
@@ -127,63 +133,63 @@ void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int directio
} \
}
-addr_t read_reg(struct CPUState* cpu, int reg, int size)
+addr_t read_reg(struct CPUState *cpu, int reg, int size)
{
switch (size) {
- case 1:
- return cpu->hvf_x86->regs[reg].lx;
- case 2:
- return cpu->hvf_x86->regs[reg].rx;
- case 4:
- return cpu->hvf_x86->regs[reg].erx;
- case 8:
- return cpu->hvf_x86->regs[reg].rrx;
- default:
- VM_PANIC_ON("read_reg size");
+ case 1:
+ return cpu->hvf_x86->regs[reg].lx;
+ case 2:
+ return cpu->hvf_x86->regs[reg].rx;
+ case 4:
+ return cpu->hvf_x86->regs[reg].erx;
+ case 8:
+ return cpu->hvf_x86->regs[reg].rrx;
+ default:
+ VM_PANIC_ON("read_reg size");
}
return 0;
}
-void write_reg(struct CPUState* cpu, int reg, addr_t val, int size)
+void write_reg(struct CPUState *cpu, int reg, addr_t val, int size)
{
switch (size) {
- case 1:
- cpu->hvf_x86->regs[reg].lx = val;
- break;
- case 2:
- cpu->hvf_x86->regs[reg].rx = val;
- break;
- case 4:
- cpu->hvf_x86->regs[reg].rrx = (uint32_t)val;
- break;
- case 8:
- cpu->hvf_x86->regs[reg].rrx = val;
- break;
- default:
- VM_PANIC_ON("write_reg size");
+ case 1:
+ cpu->hvf_x86->regs[reg].lx = val;
+ break;
+ case 2:
+ cpu->hvf_x86->regs[reg].rx = val;
+ break;
+ case 4:
+ cpu->hvf_x86->regs[reg].rrx = (uint32_t)val;
+ break;
+ case 8:
+ cpu->hvf_x86->regs[reg].rrx = val;
+ break;
+ default:
+ VM_PANIC_ON("write_reg size");
}
}
addr_t read_val_from_reg(addr_t reg_ptr, int size)
{
addr_t 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:
- VM_PANIC_ON_EX(1, "read_val: Unknown size %d\n", size);
- break;
+ 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:
+ VM_PANIC_ON_EX(1, "read_val: Unknown size %d\n", size);
+ break;
}
return val;
}
@@ -191,30 +197,32 @@ addr_t read_val_from_reg(addr_t reg_ptr, int size)
void write_val_to_reg(addr_t reg_ptr, addr_t 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:
- VM_PANIC("write_val: Unknown size\n");
- break;
+ 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:
+ VM_PANIC("write_val: Unknown size\n");
+ break;
}
}
-static bool is_host_reg(struct CPUState* cpu, addr_t ptr) {
+static bool is_host_reg(struct CPUState *cpu, addr_t ptr)
+{
return (ptr > (addr_t)cpu && ptr < (addr_t)cpu + sizeof(struct CPUState)) ||
- (ptr > (addr_t)cpu->hvf_x86 && ptr < (addr_t)(cpu->hvf_x86 + sizeof(struct hvf_x86_state)));
+ (ptr > (addr_t)cpu->hvf_x86 && ptr <
+ (addr_t)(cpu->hvf_x86 + sizeof(struct hvf_x86_state)));
}
-void write_val_ext(struct CPUState* cpu, addr_t ptr, addr_t val, int size)
+void write_val_ext(struct CPUState *cpu, addr_t ptr, addr_t val, int size)
{
if (is_host_reg(cpu, ptr)) {
write_val_to_reg(ptr, val, size);
@@ -223,68 +231,77 @@ void write_val_ext(struct CPUState* cpu, addr_t ptr, addr_t val, int size)
vmx_write_mem(cpu, ptr, &val, size);
}
-uint8_t *read_mmio(struct CPUState* cpu, addr_t ptr, int bytes)
+uint8_t *read_mmio(struct CPUState *cpu, addr_t ptr, int bytes)
{
vmx_read_mem(cpu, cpu->hvf_x86->mmio_buf, ptr, bytes);
return cpu->hvf_x86->mmio_buf;
}
-addr_t read_val_ext(struct CPUState* cpu, addr_t ptr, int size)
+addr_t read_val_ext(struct CPUState *cpu, addr_t ptr, int size)
{
addr_t val;
uint8_t *mmio_ptr;
-
+
if (is_host_reg(cpu, ptr)) {
return read_val_from_reg(ptr, size);
}
-
+
mmio_ptr = read_mmio(cpu, 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;
+ 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(struct CPUState *cpu, struct x86_decode *decode, int n, bool val_op0, bool val_op1, bool val_op2)
+static void fetch_operands(struct CPUState *cpu, 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(cpu, decode, &decode->op[i]);
- if (calc_val[i])
- decode->op[i].val = read_val_ext(cpu, decode->op[i].ptr, decode->operand_size);
- break;
- case X86_VAR_OFFSET:
- decode->op[i].ptr = decode_linear_addr(cpu, decode, decode->op[i].ptr, REG_SEG_DS);
- if (calc_val[i])
- decode->op[i].val = read_val_ext(cpu, decode->op[i].ptr, decode->operand_size);
- break;
- default:
- break;
+ 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(cpu, decode, &decode->op[i]);
+ if (calc_val[i]) {
+ decode->op[i].val = read_val_ext(cpu, decode->op[i].ptr,
+ decode->operand_size);
+ }
+ break;
+ case X86_VAR_OFFSET:
+ decode->op[i].ptr = decode_linear_addr(cpu, decode,
+ decode->op[i].ptr,
+ REG_SEG_DS);
+ if (calc_val[i]) {
+ decode->op[i].val = read_val_ext(cpu, decode->op[i].ptr,
+ decode->operand_size);
+ }
+ break;
+ default:
+ break;
}
}
}
@@ -292,7 +309,8 @@ static void fetch_operands(struct CPUState *cpu, struct x86_decode *decode, int
static void exec_mov(struct CPUState *cpu, struct x86_decode *decode)
{
fetch_operands(cpu, decode, 2, false, true, false);
- write_val_ext(cpu, decode->op[0].ptr, decode->op[1].val, decode->operand_size);
+ write_val_ext(cpu, decode->op[0].ptr, decode->op[1].val,
+ decode->operand_size);
RIP(cpu) += decode->len;
}
@@ -341,7 +359,7 @@ static void exec_xor(struct CPUState *cpu, struct x86_decode *decode)
static void exec_neg(struct CPUState *cpu, struct x86_decode *decode)
{
- //EXEC_2OP_ARITH_CMD(cpu, decode, -, SET_FLAGS_OSZAPC_SUB, false);
+ /*EXEC_2OP_ARITH_CMD(cpu, decode, -, SET_FLAGS_OSZAPC_SUB, false);*/
int32_t val;
fetch_operands(cpu, decode, 2, true, true, false);
@@ -350,17 +368,15 @@ static void exec_neg(struct CPUState *cpu, struct x86_decode *decode)
if (4 == decode->operand_size) {
SET_FLAGS_OSZAPC_SUB_32(0, 0 - val, val);
- }
- else if (2 == decode->operand_size) {
+ } else if (2 == decode->operand_size) {
SET_FLAGS_OSZAPC_SUB_16(0, 0 - val, val);
- }
- else if (1 == decode->operand_size) {
+ } else if (1 == decode->operand_size) {
SET_FLAGS_OSZAPC_SUB_8(0, 0 - val, val);
} else {
VM_PANIC("bad op size\n");
}
- //lflags_to_rflags(cpu);
+ /*lflags_to_rflags(cpu);*/
RIP(cpu) += decode->len;
}
@@ -399,7 +415,8 @@ static void exec_not(struct CPUState *cpu, struct x86_decode *decode)
{
fetch_operands(cpu, decode, 1, true, false, false);
- write_val_ext(cpu, decode->op[0].ptr, ~decode->op[0].val, decode->operand_size);
+ write_val_ext(cpu, decode->op[0].ptr, ~decode->op[0].val,
+ decode->operand_size);
RIP(cpu) += decode->len;
}
@@ -410,10 +427,11 @@ void exec_movzx(struct CPUState *cpu, struct x86_decode *decode)
fetch_operands(cpu, decode, 1, false, false, false);
- if (0xb6 == decode->opcode[1])
+ if (0xb6 == decode->opcode[1]) {
src_op_size = 1;
- else
+ } else {
src_op_size = 2;
+ }
decode->operand_size = src_op_size;
calc_modrm_operand(cpu, decode, &decode->op[1]);
decode->op[1].val = read_val_ext(cpu, decode->op[1].ptr, src_op_size);
@@ -425,21 +443,22 @@ void exec_movzx(struct CPUState *cpu, struct x86_decode *decode)
static void exec_out(struct CPUState *cpu, struct x86_decode *decode)
{
switch (decode->opcode[0]) {
- case 0xe6:
- hvf_handle_io(cpu, decode->op[0].val, &AL(cpu), 1, 1, 1);
- break;
- case 0xe7:
- hvf_handle_io(cpu, decode->op[0].val, &RAX(cpu), 1, decode->operand_size, 1);
- break;
- case 0xee:
- hvf_handle_io(cpu, DX(cpu), &AL(cpu), 1, 1, 1);
- break;
- case 0xef:
- hvf_handle_io(cpu, DX(cpu), &RAX(cpu), 1, decode->operand_size, 1);
- break;
- default:
- VM_PANIC("Bad out opcode\n");
- break;
+ case 0xe6:
+ hvf_handle_io(cpu, decode->op[0].val, &AL(cpu), 1, 1, 1);
+ break;
+ case 0xe7:
+ hvf_handle_io(cpu, decode->op[0].val, &RAX(cpu), 1,
+ decode->operand_size, 1);
+ break;
+ case 0xee:
+ hvf_handle_io(cpu, DX(cpu), &AL(cpu), 1, 1, 1);
+ break;
+ case 0xef:
+ hvf_handle_io(cpu, DX(cpu), &RAX(cpu), 1, decode->operand_size, 1);
+ break;
+ default:
+ VM_PANIC("Bad out opcode\n");
+ break;
}
RIP(cpu) += decode->len;
}
@@ -448,63 +467,73 @@ static void exec_in(struct CPUState *cpu, struct x86_decode *decode)
{
addr_t val = 0;
switch (decode->opcode[0]) {
- case 0xe4:
- hvf_handle_io(cpu, decode->op[0].val, &AL(cpu), 0, 1, 1);
- break;
- case 0xe5:
- hvf_handle_io(cpu, decode->op[0].val, &val, 0, decode->operand_size, 1);
- if (decode->operand_size == 2)
- AX(cpu) = val;
- else
- RAX(cpu) = (uint32_t)val;
- break;
- case 0xec:
- hvf_handle_io(cpu, DX(cpu), &AL(cpu), 0, 1, 1);
- break;
- case 0xed:
- hvf_handle_io(cpu, DX(cpu), &val, 0, decode->operand_size, 1);
- if (decode->operand_size == 2)
- AX(cpu) = val;
- else
- RAX(cpu) = (uint32_t)val;
+ case 0xe4:
+ hvf_handle_io(cpu, decode->op[0].val, &AL(cpu), 0, 1, 1);
+ break;
+ case 0xe5:
+ hvf_handle_io(cpu, decode->op[0].val, &val, 0, decode->operand_size, 1);
+ if (decode->operand_size == 2) {
+ AX(cpu) = val;
+ } else {
+ RAX(cpu) = (uint32_t)val;
+ }
+ break;
+ case 0xec:
+ hvf_handle_io(cpu, DX(cpu), &AL(cpu), 0, 1, 1);
+ break;
+ case 0xed:
+ hvf_handle_io(cpu, DX(cpu), &val, 0, decode->operand_size, 1);
+ if (decode->operand_size == 2) {
+ AX(cpu) = val;
+ } else {
+ RAX(cpu) = (uint32_t)val;
+ }
- break;
- default:
- VM_PANIC("Bad in opcode\n");
- break;
+ break;
+ default:
+ VM_PANIC("Bad in opcode\n");
+ break;
}
RIP(cpu) += decode->len;
}
-static inline void string_increment_reg(struct CPUState * cpu, int reg, struct x86_decode *decode)
+static inline void string_increment_reg(struct CPUState *cpu, int reg,
+ struct x86_decode *decode)
{
addr_t val = read_reg(cpu, reg, decode->addressing_size);
- if (cpu->hvf_x86->rflags.df)
+ if (cpu->hvf_x86->rflags.df) {
val -= decode->operand_size;
- else
+ } else {
val += decode->operand_size;
+ }
write_reg(cpu, reg, val, decode->addressing_size);
}
-static inline void string_rep(struct CPUState * cpu, struct x86_decode *decode, void (*func)(struct CPUState *cpu, struct x86_decode *ins), int rep)
+static inline void string_rep(struct CPUState *cpu, struct x86_decode *decode,
+ void (*func)(struct CPUState *cpu,
+ struct x86_decode *ins), int rep)
{
addr_t rcx = read_reg(cpu, REG_RCX, decode->addressing_size);
while (rcx--) {
func(cpu, decode);
write_reg(cpu, REG_RCX, rcx, decode->addressing_size);
- if ((PREFIX_REP == rep) && !get_ZF(cpu))
+ if ((PREFIX_REP == rep) && !get_ZF(cpu)) {
break;
- if ((PREFIX_REPN == rep) && get_ZF(cpu))
+ }
+ if ((PREFIX_REPN == rep) && get_ZF(cpu)) {
break;
+ }
}
}
static void exec_ins_single(struct CPUState *cpu, struct x86_decode *decode)
{
- addr_t addr = linear_addr_size(cpu, RDI(cpu), decode->addressing_size, REG_SEG_ES);
+ addr_t addr = linear_addr_size(cpu, RDI(cpu), decode->addressing_size,
+ REG_SEG_ES);
- hvf_handle_io(cpu, DX(cpu), cpu->hvf_x86->mmio_buf, 0, decode->operand_size, 1);
+ hvf_handle_io(cpu, DX(cpu), cpu->hvf_x86->mmio_buf, 0,
+ decode->operand_size, 1);
vmx_write_mem(cpu, addr, cpu->hvf_x86->mmio_buf, decode->operand_size);
string_increment_reg(cpu, REG_RDI, decode);
@@ -512,10 +541,11 @@ static void exec_ins_single(struct CPUState *cpu, struct x86_decode *decode)
static void exec_ins(struct CPUState *cpu, struct x86_decode *decode)
{
- if (decode->rep)
+ if (decode->rep) {
string_rep(cpu, decode, exec_ins_single, 0);
- else
+ } else {
exec_ins_single(cpu, decode);
+ }
RIP(cpu) += decode->len;
}
@@ -525,18 +555,20 @@ static void exec_outs_single(struct CPUState *cpu, struct x86_decode *decode)
addr_t addr = decode_linear_addr(cpu, decode, RSI(cpu), REG_SEG_DS);
vmx_read_mem(cpu, cpu->hvf_x86->mmio_buf, addr, decode->operand_size);
- hvf_handle_io(cpu, DX(cpu), cpu->hvf_x86->mmio_buf, 1, decode->operand_size, 1);
+ hvf_handle_io(cpu, DX(cpu), cpu->hvf_x86->mmio_buf, 1,
+ decode->operand_size, 1);
string_increment_reg(cpu, REG_RSI, decode);
}
static void exec_outs(struct CPUState *cpu, struct x86_decode *decode)
{
- if (decode->rep)
+ if (decode->rep) {
string_rep(cpu, decode, exec_outs_single, 0);
- else
+ } else {
exec_outs_single(cpu, decode);
-
+ }
+
RIP(cpu) += decode->len;
}
@@ -545,10 +577,11 @@ static void exec_movs_single(struct CPUState *cpu, struct x86_decode *decode)
addr_t src_addr;
addr_t dst_addr;
addr_t val;
-
+
src_addr = decode_linear_addr(cpu, decode, RSI(cpu), REG_SEG_DS);
- dst_addr = linear_addr_size(cpu, RDI(cpu), decode->addressing_size, REG_SEG_ES);
-
+ dst_addr = linear_addr_size(cpu, RDI(cpu), decode->addressing_size,
+ REG_SEG_ES);
+
val = read_val_ext(cpu, src_addr, decode->operand_size);
write_val_ext(cpu, dst_addr, val, decode->operand_size);
@@ -560,9 +593,9 @@ static void exec_movs(struct CPUState *cpu, struct x86_decode *decode)
{
if (decode->rep) {
string_rep(cpu, decode, exec_movs_single, 0);
- }
- else
+ } else {
exec_movs_single(cpu, decode);
+ }
RIP(cpu) += decode->len;
}
@@ -573,7 +606,8 @@ static void exec_cmps_single(struct CPUState *cpu, struct x86_decode *decode)
addr_t dst_addr;
src_addr = decode_linear_addr(cpu, decode, RSI(cpu), REG_SEG_DS);
- dst_addr = linear_addr_size(cpu, RDI(cpu), decode->addressing_size, REG_SEG_ES);
+ dst_addr = linear_addr_size(cpu, RDI(cpu), decode->addressing_size,
+ REG_SEG_ES);
decode->op[0].type = X86_VAR_IMMEDIATE;
decode->op[0].val = read_val_ext(cpu, src_addr, decode->operand_size);
@@ -590,9 +624,9 @@ static void exec_cmps(struct CPUState *cpu, struct x86_decode *decode)
{
if (decode->rep) {
string_rep(cpu, decode, exec_cmps_single, decode->rep);
- }
- else
+ } else {
exec_cmps_single(cpu, decode);
+ }
RIP(cpu) += decode->len;
}
@@ -614,9 +648,9 @@ static void exec_stos(struct CPUState *cpu, struct x86_decode *decode)
{
if (decode->rep) {
string_rep(cpu, decode, exec_stos_single, 0);
- }
- else
+ } else {
exec_stos_single(cpu, decode);
+ }
RIP(cpu) += decode->len;
}
@@ -624,7 +658,7 @@ static void exec_stos(struct CPUState *cpu, struct x86_decode *decode)
static void exec_scas_single(struct CPUState *cpu, struct x86_decode *decode)
{
addr_t addr;
-
+
addr = linear_addr_size(cpu, RDI(cpu), decode->addressing_size, REG_SEG_ES);
decode->op[1].type = X86_VAR_IMMEDIATE;
vmx_read_mem(cpu, &decode->op[1].val, addr, decode->operand_size);
@@ -639,9 +673,9 @@ static void exec_scas(struct CPUState *cpu, struct x86_decode *decode)
decode->op[0].reg = REG_RAX;
if (decode->rep) {
string_rep(cpu, decode, exec_scas_single, decode->rep);
- }
- else
+ } else {
exec_scas_single(cpu, decode);
+ }
RIP(cpu) += decode->len;
}
@@ -650,7 +684,7 @@ static void exec_lods_single(struct CPUState *cpu, struct x86_decode *decode)
{
addr_t addr;
addr_t val = 0;
-
+
addr = decode_linear_addr(cpu, decode, RSI(cpu), REG_SEG_DS);
vmx_read_mem(cpu, &val, addr, decode->operand_size);
write_reg(cpu, REG_RAX, val, decode->operand_size);
@@ -662,14 +696,14 @@ static void exec_lods(struct CPUState *cpu, struct x86_decode *decode)
{
if (decode->rep) {
string_rep(cpu, decode, exec_lods_single, 0);
- }
- else
+ } else {
exec_lods_single(cpu, decode);
+ }
RIP(cpu) += decode->len;
}
-#define MSR_IA32_UCODE_REV 0x00000017
+#define MSR_IA32_UCODE_REV 0x00000017
void simulate_rdmsr(struct CPUState *cpu)
{
@@ -679,83 +713,83 @@ void simulate_rdmsr(struct CPUState *cpu)
uint64_t val = 0;
switch (msr) {
- case MSR_IA32_TSC:
- val = rdtscp() + rvmcs(cpu->hvf_fd, VMCS_TSC_OFFSET);
- break;
- case MSR_IA32_APICBASE:
- val = cpu_get_apic_base(X86_CPU(cpu)->apic_state);
- break;
- case MSR_IA32_UCODE_REV:
- val = (0x100000000ULL << 32) | 0x100000000ULL;
- break;
- case MSR_EFER:
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER);
- break;
- case MSR_FSBASE:
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE);
- break;
- case MSR_GSBASE:
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE);
- break;
- case MSR_KERNELGSBASE:
- val = rvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE);
- break;
- case MSR_STAR:
- abort();
- break;
- case MSR_LSTAR:
- abort();
- break;
- case MSR_CSTAR:
- abort();
- break;
- case MSR_IA32_MISC_ENABLE:
- val = env->msr_ia32_misc_enable;
- break;
- case MSR_MTRRphysBase(0):
- case MSR_MTRRphysBase(1):
- case MSR_MTRRphysBase(2):
- case MSR_MTRRphysBase(3):
- case MSR_MTRRphysBase(4):
- case MSR_MTRRphysBase(5):
- case MSR_MTRRphysBase(6):
- case MSR_MTRRphysBase(7):
- val = env->mtrr_var[(ECX(cpu) - MSR_MTRRphysBase(0)) / 2].base;
- break;
- case MSR_MTRRphysMask(0):
- case MSR_MTRRphysMask(1):
- case MSR_MTRRphysMask(2):
- case MSR_MTRRphysMask(3):
- case MSR_MTRRphysMask(4):
- case MSR_MTRRphysMask(5):
- case MSR_MTRRphysMask(6):
- case MSR_MTRRphysMask(7):
- val = env->mtrr_var[(ECX(cpu) - MSR_MTRRphysMask(0)) / 2].mask;
- break;
- case MSR_MTRRfix64K_00000:
- val = env->mtrr_fixed[0];
- break;
- case MSR_MTRRfix16K_80000:
- case MSR_MTRRfix16K_A0000:
- val = env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix16K_80000 + 1];
- break;
- case MSR_MTRRfix4K_C0000:
- case MSR_MTRRfix4K_C8000:
- case MSR_MTRRfix4K_D0000:
- case MSR_MTRRfix4K_D8000:
- case MSR_MTRRfix4K_E0000:
- case MSR_MTRRfix4K_E8000:
- case MSR_MTRRfix4K_F0000:
- case MSR_MTRRfix4K_F8000:
- val = env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix4K_C0000 + 3];
- break;
- case MSR_MTRRdefType:
- val = env->mtrr_deftype;
- break;
- default:
- // fprintf(stderr, "%s: unknown msr 0x%x\n", __func__, msr);
- val = 0;
- break;
+ case MSR_IA32_TSC:
+ val = rdtscp() + rvmcs(cpu->hvf_fd, VMCS_TSC_OFFSET);
+ break;
+ case MSR_IA32_APICBASE:
+ val = cpu_get_apic_base(X86_CPU(cpu)->apic_state);
+ break;
+ case MSR_IA32_UCODE_REV:
+ val = (0x100000000ULL << 32) | 0x100000000ULL;
+ break;
+ case MSR_EFER:
+ val = rvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER);
+ break;
+ case MSR_FSBASE:
+ val = rvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE);
+ break;
+ case MSR_GSBASE:
+ val = rvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE);
+ break;
+ case MSR_KERNELGSBASE:
+ val = rvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE);
+ break;
+ case MSR_STAR:
+ abort();
+ break;
+ case MSR_LSTAR:
+ abort();
+ break;
+ case MSR_CSTAR:
+ abort();
+ break;
+ case MSR_IA32_MISC_ENABLE:
+ val = env->msr_ia32_misc_enable;
+ break;
+ case MSR_MTRRphysBase(0):
+ case MSR_MTRRphysBase(1):
+ case MSR_MTRRphysBase(2):
+ case MSR_MTRRphysBase(3):
+ case MSR_MTRRphysBase(4):
+ case MSR_MTRRphysBase(5):
+ case MSR_MTRRphysBase(6):
+ case MSR_MTRRphysBase(7):
+ val = env->mtrr_var[(ECX(cpu) - MSR_MTRRphysBase(0)) / 2].base;
+ break;
+ case MSR_MTRRphysMask(0):
+ case MSR_MTRRphysMask(1):
+ case MSR_MTRRphysMask(2):
+ case MSR_MTRRphysMask(3):
+ case MSR_MTRRphysMask(4):
+ case MSR_MTRRphysMask(5):
+ case MSR_MTRRphysMask(6):
+ case MSR_MTRRphysMask(7):
+ val = env->mtrr_var[(ECX(cpu) - MSR_MTRRphysMask(0)) / 2].mask;
+ break;
+ case MSR_MTRRfix64K_00000:
+ val = env->mtrr_fixed[0];
+ break;
+ case MSR_MTRRfix16K_80000:
+ case MSR_MTRRfix16K_A0000:
+ val = env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix16K_80000 + 1];
+ break;
+ case MSR_MTRRfix4K_C0000:
+ case MSR_MTRRfix4K_C8000:
+ case MSR_MTRRfix4K_D0000:
+ case MSR_MTRRfix4K_D8000:
+ case MSR_MTRRfix4K_E0000:
+ case MSR_MTRRfix4K_E8000:
+ case MSR_MTRRfix4K_F0000:
+ case MSR_MTRRfix4K_F8000:
+ val = env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix4K_C0000 + 3];
+ break;
+ case MSR_MTRRdefType:
+ val = env->mtrr_deftype;
+ break;
+ default:
+ /* fprintf(stderr, "%s: unknown msr 0x%x\n", __func__, msr); */
+ val = 0;
+ break;
}
RAX(cpu) = (uint32_t)val;
@@ -776,88 +810,89 @@ void simulate_wrmsr(struct CPUState *cpu)
uint64_t data = ((uint64_t)EDX(cpu) << 32) | EAX(cpu);
switch (msr) {
- case MSR_IA32_TSC:
- // if (!osx_is_sierra())
- // wvmcs(cpu->hvf_fd, VMCS_TSC_OFFSET, data - rdtscp());
- //hv_vm_sync_tsc(data);
- break;
- case MSR_IA32_APICBASE:
- cpu_set_apic_base(X86_CPU(cpu)->apic_state, data);
- break;
- case MSR_FSBASE:
- wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE, data);
- break;
- case MSR_GSBASE:
- wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE, data);
- break;
- case MSR_KERNELGSBASE:
- wvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE, data);
- break;
- case MSR_STAR:
- abort();
- break;
- case MSR_LSTAR:
- abort();
- break;
- case MSR_CSTAR:
- abort();
- break;
- case MSR_EFER:
- cpu->hvf_x86->efer.efer = data;
- //printf("new efer %llx\n", EFER(cpu));
- wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, data);
- if (data & EFER_NXE)
- hv_vcpu_invalidate_tlb(cpu->hvf_fd);
- break;
- case MSR_MTRRphysBase(0):
- case MSR_MTRRphysBase(1):
- case MSR_MTRRphysBase(2):
- case MSR_MTRRphysBase(3):
- case MSR_MTRRphysBase(4):
- case MSR_MTRRphysBase(5):
- case MSR_MTRRphysBase(6):
- case MSR_MTRRphysBase(7):
- env->mtrr_var[(ECX(cpu) - MSR_MTRRphysBase(0)) / 2].base = data;
- break;
- case MSR_MTRRphysMask(0):
- case MSR_MTRRphysMask(1):
- case MSR_MTRRphysMask(2):
- case MSR_MTRRphysMask(3):
- case MSR_MTRRphysMask(4):
- case MSR_MTRRphysMask(5):
- case MSR_MTRRphysMask(6):
- case MSR_MTRRphysMask(7):
- env->mtrr_var[(ECX(cpu) - MSR_MTRRphysMask(0)) / 2].mask = data;
- break;
- case MSR_MTRRfix64K_00000:
- env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix64K_00000] = data;
- break;
- case MSR_MTRRfix16K_80000:
- case MSR_MTRRfix16K_A0000:
- env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix16K_80000 + 1] = data;
- break;
- case MSR_MTRRfix4K_C0000:
- case MSR_MTRRfix4K_C8000:
- case MSR_MTRRfix4K_D0000:
- case MSR_MTRRfix4K_D8000:
- case MSR_MTRRfix4K_E0000:
- case MSR_MTRRfix4K_E8000:
- case MSR_MTRRfix4K_F0000:
- case MSR_MTRRfix4K_F8000:
- env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix4K_C0000 + 3] = data;
- break;
- case MSR_MTRRdefType:
- env->mtrr_deftype = data;
- break;
- default:
- break;
+ case MSR_IA32_TSC:
+ /* if (!osx_is_sierra())
+ wvmcs(cpu->hvf_fd, VMCS_TSC_OFFSET, data - rdtscp());
+ hv_vm_sync_tsc(data);*/
+ break;
+ case MSR_IA32_APICBASE:
+ cpu_set_apic_base(X86_CPU(cpu)->apic_state, data);
+ break;
+ case MSR_FSBASE:
+ wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE, data);
+ break;
+ case MSR_GSBASE:
+ wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE, data);
+ break;
+ case MSR_KERNELGSBASE:
+ wvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE, data);
+ break;
+ case MSR_STAR:
+ abort();
+ break;
+ case MSR_LSTAR:
+ abort();
+ break;
+ case MSR_CSTAR:
+ abort();
+ break;
+ case MSR_EFER:
+ cpu->hvf_x86->efer.efer = data;
+ /*printf("new efer %llx\n", EFER(cpu));*/
+ wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, data);
+ if (data & EFER_NXE) {
+ hv_vcpu_invalidate_tlb(cpu->hvf_fd);
+ }
+ break;
+ case MSR_MTRRphysBase(0):
+ case MSR_MTRRphysBase(1):
+ case MSR_MTRRphysBase(2):
+ case MSR_MTRRphysBase(3):
+ case MSR_MTRRphysBase(4):
+ case MSR_MTRRphysBase(5):
+ case MSR_MTRRphysBase(6):
+ case MSR_MTRRphysBase(7):
+ env->mtrr_var[(ECX(cpu) - MSR_MTRRphysBase(0)) / 2].base = data;
+ break;
+ case MSR_MTRRphysMask(0):
+ case MSR_MTRRphysMask(1):
+ case MSR_MTRRphysMask(2):
+ case MSR_MTRRphysMask(3):
+ case MSR_MTRRphysMask(4):
+ case MSR_MTRRphysMask(5):
+ case MSR_MTRRphysMask(6):
+ case MSR_MTRRphysMask(7):
+ env->mtrr_var[(ECX(cpu) - MSR_MTRRphysMask(0)) / 2].mask = data;
+ break;
+ case MSR_MTRRfix64K_00000:
+ env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix64K_00000] = data;
+ break;
+ case MSR_MTRRfix16K_80000:
+ case MSR_MTRRfix16K_A0000:
+ env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix16K_80000 + 1] = data;
+ break;
+ case MSR_MTRRfix4K_C0000:
+ case MSR_MTRRfix4K_C8000:
+ case MSR_MTRRfix4K_D0000:
+ case MSR_MTRRfix4K_D8000:
+ case MSR_MTRRfix4K_E0000:
+ case MSR_MTRRfix4K_E8000:
+ case MSR_MTRRfix4K_F0000:
+ case MSR_MTRRfix4K_F8000:
+ env->mtrr_fixed[ECX(cpu) - MSR_MTRRfix4K_C0000 + 3] = data;
+ break;
+ case MSR_MTRRdefType:
+ env->mtrr_deftype = data;
+ break;
+ default:
+ break;
}
/* Related to support known hypervisor interface */
- // if (g_hypervisor_iface)
- // g_hypervisor_iface->wrmsr_handler(cpu, msr, data);
+ /* if (g_hypervisor_iface)
+ g_hypervisor_iface->wrmsr_handler(cpu, msr, data);
- //printf("write msr %llx\n", RCX(cpu));
+ printf("write msr %llx\n", RCX(cpu));*/
}
static void exec_wrmsr(struct CPUState *cpu, struct x86_decode *decode)
@@ -893,24 +928,26 @@ static void do_bt(struct CPUState *cpu, struct x86_decode *decode, int flag)
VM_PANIC("bt 64bit\n");
}
}
- decode->op[0].val = read_val_ext(cpu, decode->op[0].ptr, decode->operand_size);
+ decode->op[0].val = read_val_ext(cpu, decode->op[0].ptr,
+ decode->operand_size);
cf = (decode->op[0].val >> index) & 0x01;
switch (flag) {
- case 0:
- set_CF(cpu, 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;
+ case 0:
+ set_CF(cpu, 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(cpu, decode->op[0].ptr, decode->op[0].val, decode->operand_size);
+ write_val_ext(cpu, decode->op[0].ptr, decode->op[0].val,
+ decode->operand_size);
set_CF(cpu, cf);
}
@@ -946,58 +983,59 @@ void exec_shl(struct CPUState *cpu, struct x86_decode *decode)
fetch_operands(cpu, decode, 2, true, true, false);
count = decode->op[1].val;
- count &= 0x1f; // count is masked to 5 bits
- if (!count)
+ 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(cpu, decode->op[0].ptr, res, 1);
- SET_FLAGS_OSZAPC_LOGIC_8(res);
- SET_FLAGS_OxxxxC(cpu, of, cf);
- break;
+ 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);
}
- 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(cpu, decode->op[0].ptr, res, 2);
- SET_FLAGS_OSZAPC_LOGIC_16(res);
- SET_FLAGS_OxxxxC(cpu, of, cf);
- break;
- }
- case 4:
- {
- uint32_t res = decode->op[0].val << count;
-
- write_val_ext(cpu, decode->op[0].ptr, res, 4);
- SET_FLAGS_OSZAPC_LOGIC_32(res);
- cf = (decode->op[0].val >> (32 - count)) & 0x1;
- of = cf ^ (res >> 31); // of = cf ^ result31
- SET_FLAGS_OxxxxC(cpu, of, cf);
- break;
+ write_val_ext(cpu, decode->op[0].ptr, res, 1);
+ SET_FLAGS_OSZAPC_LOGIC_8(res);
+ SET_FLAGS_OxxxxC(cpu, 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 */
}
- default:
- abort();
+
+ write_val_ext(cpu, decode->op[0].ptr, res, 2);
+ SET_FLAGS_OSZAPC_LOGIC_16(res);
+ SET_FLAGS_OxxxxC(cpu, of, cf);
+ break;
+ }
+ case 4:
+ {
+ uint32_t res = decode->op[0].val << count;
+
+ write_val_ext(cpu, decode->op[0].ptr, res, 4);
+ SET_FLAGS_OSZAPC_LOGIC_32(res);
+ cf = (decode->op[0].val >> (32 - count)) & 0x1;
+ of = cf ^ (res >> 31); /* of = cf ^ result31 */
+ SET_FLAGS_OxxxxC(cpu, of, cf);
+ break;
+ }
+ default:
+ abort();
}
exit:
- //lflags_to_rflags(cpu);
+ /* lflags_to_rflags(cpu); */
RIP(cpu) += decode->len;
}
@@ -1008,14 +1046,16 @@ void exec_movsx(struct CPUState *cpu, struct x86_decode *decode)
fetch_operands(cpu, decode, 2, false, false, false);
- if (0xbe == decode->opcode[1])
+ if (0xbe == decode->opcode[1]) {
src_op_size = 1;
- else
+ } else {
src_op_size = 2;
+ }
decode->operand_size = src_op_size;
calc_modrm_operand(cpu, decode, &decode->op[1]);
- decode->op[1].val = sign(read_val_ext(cpu, decode->op[1].ptr, src_op_size), src_op_size);
+ decode->op[1].val = sign(read_val_ext(cpu, decode->op[1].ptr, src_op_size),
+ src_op_size);
write_val_ext(cpu, decode->op[0].ptr, decode->op[1].val, op_size);
@@ -1030,68 +1070,71 @@ void exec_ror(struct CPUState *cpu, struct x86_decode *decode)
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(cpu, 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(cpu, decode->op[0].ptr, res, 1);
- bit6 = (res >> 6) & 1;
- bit7 = (res >> 7) & 1;
- /* set eflags: ROR count affects the following flags: C, O */
+ 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(cpu, bit6 ^ bit7, bit7);
- }
- break;
+ }
+ } 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(cpu, 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(cpu, bit6 ^ bit7, bit7);
}
- 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(cpu, 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(cpu, decode->op[0].ptr, res, 2);
-
- bit14 = (res >> 14) & 1;
- bit15 = (res >> 15) & 1;
- // of = result14 ^ result15
+ 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(cpu, bit14 ^ bit15, bit15);
}
- break;
+ } 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(cpu, decode->op[0].ptr, res, 2);
+
+ bit14 = (res >> 14) & 1;
+ bit15 = (res >> 15) & 1;
+ /* of = result14 ^ result15 */
+ SET_FLAGS_OxxxxC(cpu, bit14 ^ bit15, bit15);
}
- 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(cpu, decode->op[0].ptr, res, 4);
-
- bit31 = (res >> 31) & 1;
- bit30 = (res >> 30) & 1;
- // of = result30 ^ result31
- SET_FLAGS_OxxxxC(cpu, bit30 ^ bit31, bit31);
- }
- break;
+ 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(cpu, decode->op[0].ptr, res, 4);
+
+ bit31 = (res >> 31) & 1;
+ bit30 = (res >> 30) & 1;
+ /* of = result30 ^ result31 */
+ SET_FLAGS_OxxxxC(cpu, bit30 ^ bit31, bit31);
+ }
+ break;
}
}
RIP(cpu) += decode->len;
@@ -1105,71 +1148,74 @@ void exec_rol(struct CPUState *cpu, struct x86_decode *decode)
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(cpu, 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(cpu, decode->op[0].ptr, res, 1);
- /* set eflags:
- * ROL count affects the following flags: C, O
- */
- bit0 = (res & 1);
- bit7 = (res >> 7);
+ 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(cpu, bit0 ^ bit7, bit0);
}
- break;
+ } 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(cpu, 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(cpu, bit0 ^ bit7, bit0);
}
- 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(cpu, 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(cpu, decode->op[0].ptr, res, 2);
- bit0 = (res & 0x1);
- bit15 = (res >> 15);
- // of = cf ^ result15
+ 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(cpu, bit0 ^ bit15, bit0);
}
- break;
+ } 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(cpu, decode->op[0].ptr, res, 2);
+ bit0 = (res & 0x1);
+ bit15 = (res >> 15);
+ /* of = cf ^ result15 */
+ SET_FLAGS_OxxxxC(cpu, bit0 ^ bit15, bit0);
}
- 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(cpu, decode->op[0].ptr, res, 4);
- bit0 = (res & 0x1);
- bit31 = (res >> 31);
- // of = cf ^ result31
- SET_FLAGS_OxxxxC(cpu, bit0 ^ bit31, bit0);
- }
- break;
+ 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(cpu, decode->op[0].ptr, res, 4);
+ bit0 = (res & 0x1);
+ bit31 = (res >> 31);
+ /* of = cf ^ result31 */
+ SET_FLAGS_OxxxxC(cpu, bit0 ^ bit31, bit0);
+ }
+ break;
}
}
RIP(cpu) += decode->len;
@@ -1184,70 +1230,79 @@ void exec_rcl(struct CPUState *cpu, struct x86_decode *decode)
fetch_operands(cpu, 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;
+ 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(cpu);
+ } else {
+ res = (op1_8 << count) | (get_CF(cpu) << (count - 1)) |
+ (op1_8 >> (9 - count));
+ }
- if (1 == count)
- res = (op1_8 << 1) | get_CF(cpu);
- else
- res = (op1_8 << count) | (get_CF(cpu) << (count - 1)) | (op1_8 >> (9 - count));
+ write_val_ext(cpu, decode->op[0].ptr, res, 1);
- write_val_ext(cpu, decode->op[0].ptr, res, 1);
+ cf = (op1_8 >> (8 - count)) & 0x01;
+ of = cf ^ (res >> 7); /* of = cf ^ result7 */
+ SET_FLAGS_OxxxxC(cpu, of, cf);
+ break;
+ }
+ case 2:
+ {
+ uint16_t res;
+ uint16_t op1_16 = decode->op[0].val;
- cf = (op1_8 >> (8 - count)) & 0x01;
- of = cf ^ (res >> 7); // of = cf ^ result7
- SET_FLAGS_OxxxxC(cpu, 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(cpu);
- else if (count == 16)
- res = (get_CF(cpu) << 15) | (op1_16 >> 1);
- else // 2..15
- res = (op1_16 << count) | (get_CF(cpu) << (count - 1)) | (op1_16 >> (17 - count));
-
- write_val_ext(cpu, decode->op[0].ptr, res, 2);
-
- cf = (op1_16 >> (16 - count)) & 0x1;
- of = cf ^ (res >> 15); // of = cf ^ result15
- SET_FLAGS_OxxxxC(cpu, of, cf);
+ count %= 17;
+ if (!count) {
break;
}
- case 4:
- {
- uint32_t res;
- uint32_t op1_32 = decode->op[0].val;
- if (!count)
- break;
+ if (1 == count) {
+ res = (op1_16 << 1) | get_CF(cpu);
+ } else if (count == 16) {
+ res = (get_CF(cpu) << 15) | (op1_16 >> 1);
+ } else { /* 2..15 */
+ res = (op1_16 << count) | (get_CF(cpu) << (count - 1)) |
+ (op1_16 >> (17 - count));
+ }
- if (1 == count)
- res = (op1_32 << 1) | get_CF(cpu);
- else
- res = (op1_32 << count) | (get_CF(cpu) << (count - 1)) | (op1_32 >> (33 - count));
+ write_val_ext(cpu, decode->op[0].ptr, res, 2);
- write_val_ext(cpu, decode->op[0].ptr, res, 4);
+ cf = (op1_16 >> (16 - count)) & 0x1;
+ of = cf ^ (res >> 15); /* of = cf ^ result15 */
+ SET_FLAGS_OxxxxC(cpu, of, cf);
+ break;
+ }
+ case 4:
+ {
+ uint32_t res;
+ uint32_t op1_32 = decode->op[0].val;
- cf = (op1_32 >> (32 - count)) & 0x1;
- of = cf ^ (res >> 31); // of = cf ^ result31
- SET_FLAGS_OxxxxC(cpu, of, cf);
+ if (!count) {
break;
}
+
+ if (1 == count) {
+ res = (op1_32 << 1) | get_CF(cpu);
+ } else {
+ res = (op1_32 << count) | (get_CF(cpu) << (count - 1)) |
+ (op1_32 >> (33 - count));
+ }
+
+ write_val_ext(cpu, decode->op[0].ptr, res, 4);
+
+ cf = (op1_32 >> (32 - count)) & 0x1;
+ of = cf ^ (res >> 31); /* of = cf ^ result31 */
+ SET_FLAGS_OxxxxC(cpu, of, cf);
+ break;
+ }
}
RIP(cpu) += decode->len;
}
@@ -1260,60 +1315,68 @@ void exec_rcr(struct CPUState *cpu, struct x86_decode *decode)
fetch_operands(cpu, 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;
+ 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(cpu) << (8 - count)) | (op1_8 << (9 - count));
+ count %= 9;
+ if (!count) {
+ break;
+ }
+ res = (op1_8 >> count) | (get_CF(cpu) << (8 - count)) |
+ (op1_8 << (9 - count));
- write_val_ext(cpu, decode->op[0].ptr, res, 1);
+ write_val_ext(cpu, decode->op[0].ptr, res, 1);
+
+ cf = (op1_8 >> (count - 1)) & 0x1;
+ of = (((res << 1) ^ res) >> 7) & 0x1; /* of = result6 ^ result7 */
+ SET_FLAGS_OxxxxC(cpu, of, cf);
+ break;
+ }
+ case 2:
+ {
+ uint16_t op1_16 = decode->op[0].val;
+ uint16_t res;
- cf = (op1_8 >> (count - 1)) & 0x1;
- of = (((res << 1) ^ res) >> 7) & 0x1; // of = result6 ^ result7
- SET_FLAGS_OxxxxC(cpu, of, cf);
+ count %= 17;
+ if (!count) {
break;
}
- case 2:
- {
- uint16_t op1_16 = decode->op[0].val;
- uint16_t res;
+ res = (op1_16 >> count) | (get_CF(cpu) << (16 - count)) |
+ (op1_16 << (17 - count));
- count %= 17;
- if (!count)
- break;
- res = (op1_16 >> count) | (get_CF(cpu) << (16 - count)) | (op1_16 << (17 - count));
+ write_val_ext(cpu, decode->op[0].ptr, res, 2);
- write_val_ext(cpu, 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(cpu, of, cf);
+ break;
+ }
+ case 4:
+ {
+ uint32_t res;
+ uint32_t op1_32 = decode->op[0].val;
- cf = (op1_16 >> (count - 1)) & 0x1;
- of = ((uint16_t)((res << 1) ^ res) >> 15) & 0x1; // of = result15 ^ result14
- SET_FLAGS_OxxxxC(cpu, of, cf);
+ if (!count) {
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(cpu) << 31);
- else
- res = (op1_32 >> count) | (get_CF(cpu) << (32 - count)) | (op1_32 << (33 - count));
- write_val_ext(cpu, decode->op[0].ptr, res, 4);
+ if (1 == count) {
+ res = (op1_32 >> 1) | (get_CF(cpu) << 31);
+ } else {
+ res = (op1_32 >> count) | (get_CF(cpu) << (32 - count)) |
+ (op1_32 << (33 - count));
+ }
- cf = (op1_32 >> (count - 1)) & 0x1;
- of = ((res << 1) ^ res) >> 31; // of = result30 ^ result31
- SET_FLAGS_OxxxxC(cpu, of, cf);
- break;
+ write_val_ext(cpu, decode->op[0].ptr, res, 4);
+
+ cf = (op1_32 >> (count - 1)) & 0x1;
+ of = ((res << 1) ^ res) >> 31; /* of = result30 ^ result31 */
+ SET_FLAGS_OxxxxC(cpu, of, cf);
+ break;
}
}
RIP(cpu) += decode->len;
@@ -1323,8 +1386,10 @@ static void exec_xchg(struct CPUState *cpu, struct x86_decode *decode)
{
fetch_operands(cpu, decode, 2, true, true, false);
- write_val_ext(cpu, decode->op[0].ptr, decode->op[1].val, decode->operand_size);
- write_val_ext(cpu, decode->op[1].ptr, decode->op[0].val, decode->operand_size);
+ write_val_ext(cpu, decode->op[0].ptr, decode->op[1].val,
+ decode->operand_size);
+ write_val_ext(cpu, decode->op[1].ptr, decode->op[0].val,
+ decode->operand_size);
RIP(cpu) += decode->len;
}
@@ -1332,7 +1397,8 @@ static void exec_xchg(struct CPUState *cpu, struct x86_decode *decode)
static void exec_xadd(struct CPUState *cpu, struct x86_decode *decode)
{
EXEC_2OP_ARITH_CMD(cpu, decode, +, SET_FLAGS_OSZAPC_ADD, true);
- write_val_ext(cpu, decode->op[1].ptr, decode->op[0].val, decode->operand_size);
+ write_val_ext(cpu, decode->op[1].ptr, decode->op[0].val,
+ decode->operand_size);
RIP(cpu) += decode->len;
}
@@ -1388,13 +1454,9 @@ static struct cmd_handler _cmd_handler[X86_DECODE_CMD_LAST];
static void init_cmd_handler(CPUState *cpu)
{
int i;
- for (i = 0; i < ARRAY_SIZE(handlers); i++)
+ for (i = 0; i < ARRAY_SIZE(handlers); i++) {
_cmd_handler[handlers[i].cmd] = handlers[i];
-}
-
-static void print_debug(struct CPUState *cpu)
-{
- printf("%llx: eax %llx ebx %llx ecx %llx edx %llx esi %llx edi %llx ebp %llx esp %llx flags %llx\n", RIP(cpu), RAX(cpu), RBX(cpu), RCX(cpu), RDX(cpu), RSI(cpu), RDI(cpu), RBP(cpu), RSP(cpu), EFLAGS(cpu));
+ }
}
void load_regs(struct CPUState *cpu)
@@ -1408,14 +1470,13 @@ void load_regs(struct CPUState *cpu)
RRX(cpu, REG_RDI) = rreg(cpu->hvf_fd, HV_X86_RDI);
RRX(cpu, REG_RSP) = rreg(cpu->hvf_fd, HV_X86_RSP);
RRX(cpu, REG_RBP) = rreg(cpu->hvf_fd, HV_X86_RBP);
- for (i = 8; i < 16; i++)
+ for (i = 8; i < 16; i++) {
RRX(cpu, i) = rreg(cpu->hvf_fd, HV_X86_RAX + i);
-
+ }
+
RFLAGS(cpu) = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
rflags_to_lflags(cpu);
RIP(cpu) = rreg(cpu->hvf_fd, HV_X86_RIP);
-
- //print_debug(cpu);
}
void store_regs(struct CPUState *cpu)
@@ -1429,32 +1490,36 @@ void store_regs(struct CPUState *cpu)
wreg(cpu->hvf_fd, HV_X86_RDI, RDI(cpu));
wreg(cpu->hvf_fd, HV_X86_RBP, RBP(cpu));
wreg(cpu->hvf_fd, HV_X86_RSP, RSP(cpu));
- for (i = 8; i < 16; i++)
+ for (i = 8; i < 16; i++) {
wreg(cpu->hvf_fd, HV_X86_RAX + i, RRX(cpu, i));
-
+ }
+
lflags_to_rflags(cpu);
wreg(cpu->hvf_fd, HV_X86_RFLAGS, RFLAGS(cpu));
macvm_set_rip(cpu, RIP(cpu));
-
- //print_debug(cpu);
}
bool exec_instruction(struct CPUState *cpu, struct x86_decode *ins)
{
- //if (hvf_vcpu_id(cpu))
- //printf("%d, %llx: exec_instruction %s\n", hvf_vcpu_id(cpu), RIP(cpu), decode_cmd_to_string(ins->cmd));
-
+ /*if (hvf_vcpu_id(cpu))
+ printf("%d, %llx: exec_instruction %s\n", hvf_vcpu_id(cpu), RIP(cpu),
+ decode_cmd_to_string(ins->cmd));*/
+
if (0 && ins->is_fpu) {
VM_PANIC("emulate fpu\n");
} else {
if (!_cmd_handler[ins->cmd].handler) {
- printf("Unimplemented handler (%llx) for %d (%x %x) \n", RIP(cpu), ins->cmd, ins->opcode[0],
- ins->opcode_len > 1 ? ins->opcode[1] : 0);
+ printf("Unimplemented handler (%llx) for %d (%x %x) \n", RIP(cpu),
+ ins->cmd, ins->opcode[0],
+ ins->opcode_len > 1 ? ins->opcode[1] : 0);
RIP(cpu) += ins->len;
return true;
}
-
- VM_PANIC_ON_EX(!_cmd_handler[ins->cmd].handler, "Unimplemented handler (%llx) for %d (%x %x) \n", RIP(cpu), ins->cmd, ins->opcode[0], ins->opcode_len > 1 ? ins->opcode[1] : 0);
+
+ VM_PANIC_ON_EX(!_cmd_handler[ins->cmd].handler,
+ "Unimplemented handler (%llx) for %d (%x %x) \n", RIP(cpu),
+ ins->cmd, ins->opcode[0],
+ ins->opcode_len > 1 ? ins->opcode[1] : 0);
_cmd_handler[ins->cmd].handler(cpu, ins);
}
return true;
@@ -13,4 +13,19 @@ void store_regs(struct CPUState *cpu);
void simulate_rdmsr(struct CPUState *cpu);
void simulate_wrmsr(struct CPUState *cpu);
+addr_t read_reg(struct CPUState *cpu, int reg, int size);
+void write_reg(struct CPUState *cpu, int reg, addr_t val, int size);
+addr_t read_val_from_reg(addr_t reg_ptr, int size);
+void write_val_to_reg(addr_t reg_ptr, addr_t val, int size);
+void write_val_ext(struct CPUState *cpu, addr_t ptr, addr_t val, int size);
+uint8_t *read_mmio(struct CPUState *cpu, addr_t ptr, int bytes);
+addr_t read_val_ext(struct CPUState *cpu, addr_t ptr, int size);
+
+void exec_movzx(struct CPUState *cpu, struct x86_decode *decode);
+void exec_shl(struct CPUState *cpu, struct x86_decode *decode);
+void exec_movsx(struct CPUState *cpu, struct x86_decode *decode);
+void exec_ror(struct CPUState *cpu, struct x86_decode *decode);
+void exec_rol(struct CPUState *cpu, struct x86_decode *decode);
+void exec_rcl(struct CPUState *cpu, struct x86_decode *decode);
+void exec_rcr(struct CPUState *cpu, struct x86_decode *decode);
#endif
@@ -32,65 +32,78 @@ void SET_FLAGS_OxxxxC(struct CPUState *cpu, uint32_t new_of, uint32_t new_cf)
{
uint32_t temp_po = new_of ^ new_cf;
cpu->hvf_x86->lflags.auxbits &= ~(LF_MASK_PO | LF_MASK_CF);
- cpu->hvf_x86->lflags.auxbits |= (temp_po << LF_BIT_PO) | (new_cf << LF_BIT_CF);
+ cpu->hvf_x86->lflags.auxbits |= (temp_po << LF_BIT_PO) |
+ (new_cf << LF_BIT_CF);
}
-void SET_FLAGS_OSZAPC_SUB32(struct CPUState *cpu, uint32_t v1, uint32_t v2, uint32_t diff)
+void SET_FLAGS_OSZAPC_SUB32(struct CPUState *cpu, uint32_t v1, uint32_t v2,
+ uint32_t diff)
{
SET_FLAGS_OSZAPC_SUB_32(v1, v2, diff);
}
-void SET_FLAGS_OSZAPC_SUB16(struct CPUState *cpu, uint16_t v1, uint16_t v2, uint16_t diff)
+void SET_FLAGS_OSZAPC_SUB16(struct CPUState *cpu, uint16_t v1, uint16_t v2,
+ uint16_t diff)
{
SET_FLAGS_OSZAPC_SUB_16(v1, v2, diff);
}
-void SET_FLAGS_OSZAPC_SUB8(struct CPUState *cpu, uint8_t v1, uint8_t v2, uint8_t diff)
+void SET_FLAGS_OSZAPC_SUB8(struct CPUState *cpu, uint8_t v1, uint8_t v2,
+ uint8_t diff)
{
SET_FLAGS_OSZAPC_SUB_8(v1, v2, diff);
}
-void SET_FLAGS_OSZAPC_ADD32(struct CPUState *cpu, uint32_t v1, uint32_t v2, uint32_t diff)
+void SET_FLAGS_OSZAPC_ADD32(struct CPUState *cpu, uint32_t v1, uint32_t v2,
+ uint32_t diff)
{
SET_FLAGS_OSZAPC_ADD_32(v1, v2, diff);
}
-void SET_FLAGS_OSZAPC_ADD16(struct CPUState *cpu, uint16_t v1, uint16_t v2, uint16_t diff)
+void SET_FLAGS_OSZAPC_ADD16(struct CPUState *cpu, uint16_t v1, uint16_t v2,
+ uint16_t diff)
{
SET_FLAGS_OSZAPC_ADD_16(v1, v2, diff);
}
-void SET_FLAGS_OSZAPC_ADD8(struct CPUState *cpu, uint8_t v1, uint8_t v2, uint8_t diff)
+void SET_FLAGS_OSZAPC_ADD8(struct CPUState *cpu, uint8_t v1, uint8_t v2,
+ uint8_t diff)
{
SET_FLAGS_OSZAPC_ADD_8(v1, v2, diff);
}
-void SET_FLAGS_OSZAP_SUB32(struct CPUState *cpu, uint32_t v1, uint32_t v2, uint32_t diff)
+void SET_FLAGS_OSZAP_SUB32(struct CPUState *cpu, uint32_t v1, uint32_t v2,
+ uint32_t diff)
{
SET_FLAGS_OSZAP_SUB_32(v1, v2, diff);
}
-void SET_FLAGS_OSZAP_SUB16(struct CPUState *cpu, uint16_t v1, uint16_t v2, uint16_t diff)
+void SET_FLAGS_OSZAP_SUB16(struct CPUState *cpu, uint16_t v1, uint16_t v2,
+ uint16_t diff)
{
SET_FLAGS_OSZAP_SUB_16(v1, v2, diff);
}
-void SET_FLAGS_OSZAP_SUB8(struct CPUState *cpu, uint8_t v1, uint8_t v2, uint8_t diff)
+void SET_FLAGS_OSZAP_SUB8(struct CPUState *cpu, uint8_t v1, uint8_t v2,
+ uint8_t diff)
{
SET_FLAGS_OSZAP_SUB_8(v1, v2, diff);
}
-void SET_FLAGS_OSZAP_ADD32(struct CPUState *cpu, uint32_t v1, uint32_t v2, uint32_t diff)
+void SET_FLAGS_OSZAP_ADD32(struct CPUState *cpu, uint32_t v1, uint32_t v2,
+ uint32_t diff)
{
SET_FLAGS_OSZAP_ADD_32(v1, v2, diff);
}
-void SET_FLAGS_OSZAP_ADD16(struct CPUState *cpu, uint16_t v1, uint16_t v2, uint16_t diff)
+void SET_FLAGS_OSZAP_ADD16(struct CPUState *cpu, uint16_t v1, uint16_t v2,
+ uint16_t diff)
{
SET_FLAGS_OSZAP_ADD_16(v1, v2, diff);
}
-void SET_FLAGS_OSZAP_ADD8(struct CPUState *cpu, uint8_t v1, uint8_t v2, uint8_t diff)
+void SET_FLAGS_OSZAP_ADD8(struct CPUState *cpu, uint8_t v1, uint8_t v2,
+ uint8_t diff)
{
SET_FLAGS_OSZAP_ADD_8(v1, v2, diff);
}
@@ -264,19 +277,22 @@ bool get_ZF(struct CPUState *cpu)
void set_ZF(struct CPUState *cpu, bool val)
{
if (val) {
- cpu->hvf_x86->lflags.auxbits ^= (((cpu->hvf_x86->lflags.result >> LF_SIGN_BIT) & 1) << LF_BIT_SD);
- // merge the parity bits into the Parity Delta Byte
+ cpu->hvf_x86->lflags.auxbits ^=
+ (((cpu->hvf_x86->lflags.result >> LF_SIGN_BIT) & 1) << LF_BIT_SD);
+ /* merge the parity bits into the Parity Delta Byte */
uint32_t temp_pdb = (255 & cpu->hvf_x86->lflags.result);
cpu->hvf_x86->lflags.auxbits ^= (temp_pdb << LF_BIT_PDB);
- // now zero the .result value
+ /* now zero the .result value */
cpu->hvf_x86->lflags.result = 0;
- } else
+ } else {
cpu->hvf_x86->lflags.result |= (1 << 8);
+ }
}
bool get_SF(struct CPUState *cpu)
{
- return ((cpu->hvf_x86->lflags.result >> LF_SIGN_BIT) ^ (cpu->hvf_x86->lflags.auxbits >> LF_BIT_SD)) & 1;
+ return ((cpu->hvf_x86->lflags.result >> LF_SIGN_BIT) ^
+ (cpu->hvf_x86->lflags.auxbits >> LF_BIT_SD)) & 1;
}
void set_SF(struct CPUState *cpu, bool val)
@@ -55,19 +55,24 @@ typedef struct lazy_flags {
#define GET_ADD_OVERFLOW(op1, op2, result, mask) \
((((op1) ^ (result)) & ((op2) ^ (result))) & (mask))
-// *******************
-// OSZAPC
-// *******************
+/* ******************* */
+/* OSZAPC */
+/* ******************* */
/* size, carries, result */
#define SET_FLAGS_OSZAPC_SIZE(size, lf_carries, lf_result) { \
addr_t temp = ((lf_carries) & (LF_MASK_AF)) | \
(((lf_carries) >> (size - 2)) << LF_BIT_PO); \
cpu->hvf_x86->lflags.result = (addr_t)(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"); \
+ 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"); \
+ } \
cpu->hvf_x86->lflags.auxbits = (addr_t)(uint32_t)temp; \
}
@@ -87,10 +92,15 @@ typedef struct lazy_flags {
#define SET_FLAGS_OSZAPC_LOGIC_32(result_32) \
SET_FLAGS_OSZAPC_32(0, (result_32))
#define SET_FLAGS_OSZAPC_LOGIC_SIZE(size, result) { \
- if (32 == size) {SET_FLAGS_OSZAPC_LOGIC_32(result);} \
- else if (16 == size) {SET_FLAGS_OSZAPC_LOGIC_16(result);} \
- else if (8 == size) {SET_FLAGS_OSZAPC_LOGIC_8(result);} \
- else VM_PANIC("unimplemented"); \
+ if (32 == size) { \
+ SET_FLAGS_OSZAPC_LOGIC_32(result); \
+ } else if (16 == size) { \
+ SET_FLAGS_OSZAPC_LOGIC_16(result); \
+ } else if (8 == size) { \
+ SET_FLAGS_OSZAPC_LOGIC_8(result); \
+ } else { \
+ VM_PANIC("unimplemented"); \
+ } \
}
/* op1, op2, result */
@@ -109,17 +119,22 @@ typedef struct lazy_flags {
#define SET_FLAGS_OSZAPC_SUB_32(op1_32, op2_32, diff_32) \
SET_FLAGS_OSZAPC_32(SUB_COUT_VEC((op1_32), (op2_32), (diff_32)), (diff_32))
-// *******************
-// OSZAP
-// *******************
+/* ******************* */
+/* OSZAP */
+/* ******************* */
/* size, carries, result */
#define SET_FLAGS_OSZAP_SIZE(size, lf_carries, lf_result) { \
addr_t 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"); \
+ 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"); \
+ } \
cpu->hvf_x86->lflags.result = (addr_t)(int##size##_t)(lf_result); \
addr_t delta_c = (cpu->hvf_x86->lflags.auxbits ^ temp) & LF_MASK_CF; \
delta_c ^= (delta_c >> 1); \
@@ -150,9 +165,9 @@ typedef struct lazy_flags {
#define SET_FLAGS_OSZAP_SUB_32(op1_32, op2_32, diff_32) \
SET_FLAGS_OSZAP_32(SUB_COUT_VEC((op1_32), (op2_32), (diff_32)), (diff_32))
-// *******************
-// OSZAxC
-// *******************
+/* ******************* */
+/* OSZAxC */
+/* ******************* */
/* size, carries, result */
#define SET_FLAGS_OSZAxC_LOGIC_SIZE(size, lf_result) { \
bool saved_PF = getB_PF(); \
@@ -183,21 +198,33 @@ void set_OSZAPC(struct CPUState *cpu, uint32_t flags32);
void SET_FLAGS_OxxxxC(struct CPUState *cpu, uint32_t new_of, uint32_t new_cf);
-void SET_FLAGS_OSZAPC_SUB32(struct CPUState *cpu, uint32_t v1, uint32_t v2, uint32_t diff);
-void SET_FLAGS_OSZAPC_SUB16(struct CPUState *cpu, uint16_t v1, uint16_t v2, uint16_t diff);
-void SET_FLAGS_OSZAPC_SUB8(struct CPUState *cpu, uint8_t v1, uint8_t v2, uint8_t diff);
-
-void SET_FLAGS_OSZAPC_ADD32(struct CPUState *cpu, uint32_t v1, uint32_t v2, uint32_t diff);
-void SET_FLAGS_OSZAPC_ADD16(struct CPUState *cpu, uint16_t v1, uint16_t v2, uint16_t diff);
-void SET_FLAGS_OSZAPC_ADD8(struct CPUState *cpu, uint8_t v1, uint8_t v2, uint8_t diff);
-
-void SET_FLAGS_OSZAP_SUB32(struct CPUState *cpu, uint32_t v1, uint32_t v2, uint32_t diff);
-void SET_FLAGS_OSZAP_SUB16(struct CPUState *cpu, uint16_t v1, uint16_t v2, uint16_t diff);
-void SET_FLAGS_OSZAP_SUB8(struct CPUState *cpu, uint8_t v1, uint8_t v2, uint8_t diff);
-
-void SET_FLAGS_OSZAP_ADD32(struct CPUState *cpu, uint32_t v1, uint32_t v2, uint32_t diff);
-void SET_FLAGS_OSZAP_ADD16(struct CPUState *cpu, uint16_t v1, uint16_t v2, uint16_t diff);
-void SET_FLAGS_OSZAP_ADD8(struct CPUState *cpu, uint8_t v1, uint8_t v2, uint8_t diff);
+void SET_FLAGS_OSZAPC_SUB32(struct CPUState *cpu, uint32_t v1, uint32_t v2,
+ uint32_t diff);
+void SET_FLAGS_OSZAPC_SUB16(struct CPUState *cpu, uint16_t v1, uint16_t v2,
+ uint16_t diff);
+void SET_FLAGS_OSZAPC_SUB8(struct CPUState *cpu, uint8_t v1, uint8_t v2,
+ uint8_t diff);
+
+void SET_FLAGS_OSZAPC_ADD32(struct CPUState *cpu, uint32_t v1, uint32_t v2,
+ uint32_t diff);
+void SET_FLAGS_OSZAPC_ADD16(struct CPUState *cpu, uint16_t v1, uint16_t v2,
+ uint16_t diff);
+void SET_FLAGS_OSZAPC_ADD8(struct CPUState *cpu, uint8_t v1, uint8_t v2,
+ uint8_t diff);
+
+void SET_FLAGS_OSZAP_SUB32(struct CPUState *cpu, uint32_t v1, uint32_t v2,
+ uint32_t diff);
+void SET_FLAGS_OSZAP_SUB16(struct CPUState *cpu, uint16_t v1, uint16_t v2,
+ uint16_t diff);
+void SET_FLAGS_OSZAP_SUB8(struct CPUState *cpu, uint8_t v1, uint8_t v2,
+ uint8_t diff);
+
+void SET_FLAGS_OSZAP_ADD32(struct CPUState *cpu, uint32_t v1, uint32_t v2,
+ uint32_t diff);
+void SET_FLAGS_OSZAP_ADD16(struct CPUState *cpu, uint16_t v1, uint16_t v2,
+ uint16_t diff);
+void SET_FLAGS_OSZAP_ADD8(struct CPUState *cpu, uint8_t v1, uint8_t v2,
+ uint8_t diff);
void SET_FLAGS_OSZAPC_LOGIC32(struct CPUState *cpu, uint32_t diff);
void SET_FLAGS_OSZAPC_LOGIC16(struct CPUState *cpu, uint16_t diff);
@@ -215,4 +242,6 @@ void SET_FLAGS_SHL32(struct CPUState *cpu, uint32_t v, int count, uint32_t res);
void SET_FLAGS_SHL16(struct CPUState *cpu, uint16_t v, int count, uint16_t res);
void SET_FLAGS_SHL8(struct CPUState *cpu, uint8_t v, int count, uint8_t res);
+bool _get_OF(struct CPUState *cpu);
+bool _get_CF(struct CPUState *cpu);
#endif /* __X86_FLAGS_H__ */
@@ -54,10 +54,12 @@ struct gpt_translation {
static int gpt_top_level(struct CPUState *cpu, bool pae)
{
- if (!pae)
+ if (!pae) {
return 2;
- if (x86_is_long_mode(cpu))
+ }
+ if (x86_is_long_mode(cpu)) {
return 4;
+ }
return 3;
}
@@ -74,18 +76,21 @@ static inline int pte_size(bool pae)
}
-static bool get_pt_entry(struct CPUState *cpu, struct gpt_translation *pt, int level, bool pae)
+static bool get_pt_entry(struct CPUState *cpu, struct gpt_translation *pt,
+ int level, bool pae)
{
int index;
uint64_t pte = 0;
addr_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK;
addr_t gpa = pt->pte[level] & page_mask;
- if (level == 3 && !x86_is_long_mode(cpu))
+ if (level == 3 && !x86_is_long_mode(cpu)) {
gpa = pt->pte[level];
+ }
index = gpt_entry(pt->gva, level, pae);
- address_space_rw(&address_space_memory, gpa + index * pte_size(pae), MEMTXATTRS_UNSPECIFIED, (uint8_t *)&pte, pte_size(pae), 0);
+ address_space_rw(&address_space_memory, gpa + index * pte_size(pae),
+ MEMTXATTRS_UNSPECIFIED, (uint8_t *)&pte, pte_size(pae), 0);
pt->pte[level - 1] = pte;
@@ -93,32 +98,38 @@ static bool get_pt_entry(struct CPUState *cpu, struct gpt_translation *pt, int l
}
/* test page table entry */
-static bool test_pt_entry(struct CPUState *cpu, struct gpt_translation *pt, int level, bool *is_large, bool pae)
+static bool test_pt_entry(struct CPUState *cpu, struct gpt_translation *pt,
+ int level, bool *is_large, bool pae)
{
uint64_t pte = pt->pte[level];
-
- if (pt->write_access)
+
+ if (pt->write_access) {
pt->err_code |= MMU_PAGE_WT;
- if (pt->user_access)
+ }
+ if (pt->user_access) {
pt->err_code |= MMU_PAGE_US;
- if (pt->exec_access)
+ }
+ if (pt->exec_access) {
pt->err_code |= MMU_PAGE_NX;
+ }
if (!pte_present(pte)) {
- addr_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK;
+ /* addr_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK; */
return false;
}
-
- if (pae && !x86_is_long_mode(cpu) && 2 == level)
+
+ if (pae && !x86_is_long_mode(cpu) && 2 == level) {
goto exit;
-
+ }
+
if (1 == level && pte_large_page(pte)) {
pt->err_code |= MMU_PAGE_PT;
*is_large = true;
}
- if (!level)
+ if (!level) {
pt->err_code |= MMU_PAGE_PT;
-
+ }
+
addr_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
/* check protection */
if (cr0 & CR0_WP) {
@@ -134,7 +145,7 @@ static bool test_pt_entry(struct CPUState *cpu, struct gpt_translation *pt, int
if (pae && pt->exec_access && !pte_exec_access(pte)) {
return false;
}
-
+
exit:
/* TODO: check reserved bits */
return true;
@@ -149,22 +160,24 @@ static inline uint64_t large_page_gpa(struct gpt_translation *pt, bool pae)
{
VM_PANIC_ON(!pte_large_page(pt->pte[1]))
/* 2Mb large page */
- if (pae)
+ if (pae) {
return (pt->pte[1] & PAE_PTE_LARGE_PAGE_MASK) | (pt->gva & 0x1fffff);
-
+ }
+
/* 4Mb large page */
return pse_pte_to_page(pt->pte[1]) | (pt->gva & 0x3fffff);
}
-static bool walk_gpt(struct CPUState *cpu, addr_t addr, int err_code, struct gpt_translation* pt, bool pae)
+static bool walk_gpt(struct CPUState *cpu, addr_t addr, int err_code,
+ struct gpt_translation *pt, bool pae)
{
int top_level, level;
bool is_large = false;
addr_t cr3 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR3);
addr_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK;
-
+
memset(pt, 0, sizeof(*pt));
top_level = gpt_top_level(cpu, pae);
@@ -173,7 +186,7 @@ static bool walk_gpt(struct CPUState *cpu, addr_t addr, int err_code, struct gpt
pt->user_access = (err_code & MMU_PAGE_US);
pt->write_access = (err_code & MMU_PAGE_WT);
pt->exec_access = (err_code & MMU_PAGE_NX);
-
+
for (level = top_level; level > 0; level--) {
get_pt_entry(cpu, pt, level, pae);
@@ -181,14 +194,16 @@ static bool walk_gpt(struct CPUState *cpu, addr_t addr, int err_code, struct gpt
return false;
}
- if (is_large)
+ if (is_large) {
break;
+ }
}
- if (!is_large)
+ if (!is_large) {
pt->gpa = (pt->pte[0] & page_mask) | (pt->gva & 0xfff);
- else
+ } else {
pt->gpa = large_page_gpa(pt, pae);
+ }
return true;
}
@@ -214,18 +229,20 @@ bool mmu_gva_to_gpa(struct CPUState *cpu, addr_t gva, addr_t *gpa)
return false;
}
-void vmx_write_mem(struct CPUState* cpu, addr_t gva, void *data, int bytes)
+void vmx_write_mem(struct CPUState *cpu, addr_t gva, void *data, int bytes)
{
addr_t gpa;
while (bytes > 0) {
- // copy page
+ /* copy page */
int copy = MIN(bytes, 0x1000 - (gva & 0xfff));
if (!mmu_gva_to_gpa(cpu, gva, &gpa)) {
- VM_PANIC_ON_EX(1, "%s: mmu_gva_to_gpa %llx failed\n", __FUNCTION__, gva);
+ VM_PANIC_ON_EX(1, "%s: mmu_gva_to_gpa %llx failed\n", __func__,
+ gva);
} else {
- address_space_rw(&address_space_memory, gpa, MEMTXATTRS_UNSPECIFIED, data, copy, 1);
+ address_space_rw(&address_space_memory, gpa, MEMTXATTRS_UNSPECIFIED,
+ data, copy, 1);
}
bytes -= copy;
@@ -234,18 +251,20 @@ void vmx_write_mem(struct CPUState* cpu, addr_t gva, void *data, int bytes)
}
}
-void vmx_read_mem(struct CPUState* cpu, void *data, addr_t gva, int bytes)
+void vmx_read_mem(struct CPUState *cpu, void *data, addr_t gva, int bytes)
{
addr_t gpa;
while (bytes > 0) {
- // copy page
+ /* copy page */
int copy = MIN(bytes, 0x1000 - (gva & 0xfff));
if (!mmu_gva_to_gpa(cpu, gva, &gpa)) {
- VM_PANIC_ON_EX(1, "%s: mmu_gva_to_gpa %llx failed\n", __FUNCTION__, gva);
+ VM_PANIC_ON_EX(1, "%s: mmu_gva_to_gpa %llx failed\n", __func__,
+ gva);
}
- address_space_rw(&address_space_memory, gpa, MEMTXATTRS_UNSPECIFIED, data, copy, 0);
+ address_space_rw(&address_space_memory, gpa, MEMTXATTRS_UNSPECIFIED,
+ data, copy, 0);
bytes -= copy;
gva += copy;
@@ -14,7 +14,7 @@
#define PT_GLOBAL (1 << 8)
#define PT_NX (1llu << 63)
-// error codes
+/* error codes */
#define MMU_PAGE_PT (1 << 0)
#define MMU_PAGE_WT (1 << 1)
#define MMU_PAGE_US (1 << 2)
@@ -22,7 +22,7 @@
bool mmu_gva_to_gpa(struct CPUState *cpu, addr_t gva, addr_t *gpa);
-void vmx_write_mem(struct CPUState* cpu, addr_t gva, void *data, int bytes);
-void vmx_read_mem(struct CPUState* cpu, void *data, addr_t gva, int bytes);
+void vmx_write_mem(struct CPUState *cpu, addr_t gva, void *data, int bytes);
+void vmx_read_mem(struct CPUState *cpu, void *data, addr_t gva, int bytes);
#endif /* __X86_MMU_H__ */
@@ -35,16 +35,16 @@
#include <Hypervisor/hv_vmx.h>
#include <stdint.h>
-void hvf_cpu_synchronize_state(struct CPUState* cpu_state);
-
-void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg, SegmentCache *qseg, bool is_tr)
+void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
+ SegmentCache *qseg, bool is_tr)
{
vmx_seg->sel = qseg->selector;
vmx_seg->base = qseg->base;
vmx_seg->limit = qseg->limit;
if (!qseg->selector && !x86_is_real(cpu) && !is_tr) {
- // the TR register is usable after processor reset despite having a null selector
+ /* the TR register is usable after processor reset despite
+ * having a null selector */
vmx_seg->ar = 1 << 16;
return;
}
@@ -87,19 +87,18 @@ void hvf_put_xsave(CPUState *cpu_state)
}
}
-void vmx_update_tpr(CPUState *cpu);
void hvf_put_segments(CPUState *cpu_state)
{
CPUX86State *env = &X86_CPU(cpu_state)->env;
struct vmx_segment seg;
-
+
wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_LIMIT, env->idt.limit);
wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_BASE, env->idt.base);
wvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_LIMIT, env->gdt.limit);
wvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_BASE, env->gdt.base);
- //wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR2, env->cr[2]);
+ /* wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR2, env->cr[2]); */
wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR3, env->cr[3]);
vmx_update_tpr(cpu_state);
wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IA32_EFER, env->efer);
@@ -109,7 +108,7 @@ void hvf_put_segments(CPUState *cpu_state)
hvf_set_segment(cpu_state, &seg, &env->segs[R_CS], false);
vmx_write_segment_descriptor(cpu_state, &seg, REG_SEG_CS);
-
+
hvf_set_segment(cpu_state, &seg, &env->segs[R_DS], false);
vmx_write_segment_descriptor(cpu_state, &seg, REG_SEG_DS);
@@ -130,17 +129,20 @@ void hvf_put_segments(CPUState *cpu_state)
hvf_set_segment(cpu_state, &seg, &env->ldt, false);
vmx_write_segment_descriptor(cpu_state, &seg, REG_SEG_LDTR);
-
+
hv_vcpu_flush(cpu_state->hvf_fd);
}
-
+
void hvf_put_msrs(CPUState *cpu_state)
{
CPUX86State *env = &X86_CPU(cpu_state)->env;
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS, env->sysenter_cs);
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
+ hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS,
+ env->sysenter_cs);
+ hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP,
+ env->sysenter_esp);
+ hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_EIP,
+ env->sysenter_eip);
hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_STAR, env->star);
@@ -154,8 +156,8 @@ void hvf_put_msrs(CPUState *cpu_state)
hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_GSBASE, env->segs[R_GS].base);
hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_FSBASE, env->segs[R_FS].base);
- // if (!osx_is_sierra())
- // wvmcs(cpu_state->hvf_fd, VMCS_TSC_OFFSET, env->tsc - rdtscp());
+ /* if (!osx_is_sierra())
+ wvmcs(cpu_state->hvf_fd, VMCS_TSC_OFFSET, env->tsc - rdtscp());*/
hv_vm_sync_tsc(env->tsc);
}
@@ -183,7 +185,7 @@ void hvf_get_segments(CPUState *cpu_state)
vmx_read_segment_descriptor(cpu_state, &seg, REG_SEG_CS);
hvf_get_segment(&env->segs[R_CS], &seg);
-
+
vmx_read_segment_descriptor(cpu_state, &seg, REG_SEG_DS);
hvf_get_segment(&env->segs[R_DS], &seg);
@@ -214,7 +216,7 @@ void hvf_get_segments(CPUState *cpu_state)
env->cr[2] = 0;
env->cr[3] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR3);
env->cr[4] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR4);
-
+
env->efer = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IA32_EFER);
}
@@ -222,10 +224,10 @@ void hvf_get_msrs(CPUState *cpu_state)
{
CPUX86State *env = &X86_CPU(cpu_state)->env;
uint64_t tmp;
-
+
hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS, &tmp);
env->sysenter_cs = tmp;
-
+
hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP, &tmp);
env->sysenter_esp = tmp;
@@ -242,7 +244,7 @@ void hvf_get_msrs(CPUState *cpu_state)
#endif
hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_APICBASE, &tmp);
-
+
env->tsc = rdtscp() + rvmcs(cpu_state->hvf_fd, VMCS_TSC_OFFSET);
}
@@ -269,15 +271,15 @@ int hvf_put_registers(CPUState *cpu_state)
wreg(cpu_state->hvf_fd, HV_X86_R15, env->regs[15]);
wreg(cpu_state->hvf_fd, HV_X86_RFLAGS, env->eflags);
wreg(cpu_state->hvf_fd, HV_X86_RIP, env->eip);
-
+
wreg(cpu_state->hvf_fd, HV_X86_XCR0, env->xcr0);
-
+
hvf_put_xsave(cpu_state);
-
+
hvf_put_segments(cpu_state);
-
+
hvf_put_msrs(cpu_state);
-
+
wreg(cpu_state->hvf_fd, HV_X86_DR0, env->dr[0]);
wreg(cpu_state->hvf_fd, HV_X86_DR1, env->dr[1]);
wreg(cpu_state->hvf_fd, HV_X86_DR2, env->dr[2]);
@@ -286,7 +288,7 @@ int hvf_put_registers(CPUState *cpu_state)
wreg(cpu_state->hvf_fd, HV_X86_DR5, env->dr[5]);
wreg(cpu_state->hvf_fd, HV_X86_DR6, env->dr[6]);
wreg(cpu_state->hvf_fd, HV_X86_DR7, env->dr[7]);
-
+
return 0;
}
@@ -312,16 +314,16 @@ int hvf_get_registers(CPUState *cpu_state)
env->regs[13] = rreg(cpu_state->hvf_fd, HV_X86_R13);
env->regs[14] = rreg(cpu_state->hvf_fd, HV_X86_R14);
env->regs[15] = rreg(cpu_state->hvf_fd, HV_X86_R15);
-
+
env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
env->eip = rreg(cpu_state->hvf_fd, HV_X86_RIP);
-
+
hvf_get_xsave(cpu_state);
env->xcr0 = rreg(cpu_state->hvf_fd, HV_X86_XCR0);
-
+
hvf_get_segments(cpu_state);
hvf_get_msrs(cpu_state);
-
+
env->dr[0] = rreg(cpu_state->hvf_fd, HV_X86_DR0);
env->dr[1] = rreg(cpu_state->hvf_fd, HV_X86_DR1);
env->dr[2] = rreg(cpu_state->hvf_fd, HV_X86_DR2);
@@ -330,7 +332,7 @@ int hvf_get_registers(CPUState *cpu_state)
env->dr[5] = rreg(cpu_state->hvf_fd, HV_X86_DR5);
env->dr[6] = rreg(cpu_state->hvf_fd, HV_X86_DR6);
env->dr[7] = rreg(cpu_state->hvf_fd, HV_X86_DR7);
-
+
return 0;
}
@@ -338,14 +340,16 @@ static void vmx_set_int_window_exiting(CPUState *cpu)
{
uint64_t val;
val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val | VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
+ wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val |
+ VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
}
void vmx_clear_int_window_exiting(CPUState *cpu)
{
uint64_t val;
val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val & ~VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
+ wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val &
+ ~VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
}
#define NMI_VEC 2
@@ -353,28 +357,30 @@ void vmx_clear_int_window_exiting(CPUState *cpu)
void hvf_inject_interrupts(CPUState *cpu_state)
{
X86CPU *x86cpu = X86_CPU(cpu_state);
- int allow_nmi = !(rvmcs(cpu_state->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) & VMCS_INTERRUPTIBILITY_NMI_BLOCKING);
+ int allow_nmi = !(rvmcs(cpu_state->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &
+ VMCS_INTERRUPTIBILITY_NMI_BLOCKING);
uint64_t idt_info = rvmcs(cpu_state->hvf_fd, VMCS_IDT_VECTORING_INFO);
uint64_t info = 0;
-
+
if (idt_info & VMCS_IDT_VEC_VALID) {
uint8_t vector = idt_info & 0xff;
uint64_t intr_type = idt_info & VMCS_INTR_T_MASK;
info = idt_info;
-
+
uint64_t reason = rvmcs(cpu_state->hvf_fd, VMCS_EXIT_REASON);
if (intr_type == VMCS_INTR_T_NMI && reason != EXIT_REASON_TASK_SWITCH) {
allow_nmi = 1;
vmx_clear_nmi_blocking(cpu_state);
}
-
+
if ((allow_nmi || intr_type != VMCS_INTR_T_NMI)) {
info &= ~(1 << 12); /* clear undefined bit */
if (intr_type == VMCS_INTR_T_SWINTR ||
intr_type == VMCS_INTR_T_PRIV_SWEXCEPTION ||
intr_type == VMCS_INTR_T_SWEXCEPTION) {
- uint64_t ins_len = rvmcs(cpu_state->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
+ uint64_t ins_len = rvmcs(cpu_state->hvf_fd,
+ VMCS_EXIT_INSTRUCTION_LENGTH);
wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INST_LENGTH, ins_len);
}
if (vector == EXCEPTION_BP || vector == EXCEPTION_OF) {
@@ -384,16 +390,17 @@ void hvf_inject_interrupts(CPUState *cpu_state)
*/
info &= ~VMCS_INTR_T_MASK;
info |= VMCS_INTR_T_SWEXCEPTION;
- uint64_t ins_len = rvmcs(cpu_state->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
+ uint64_t ins_len = rvmcs(cpu_state->hvf_fd,
+ VMCS_EXIT_INSTRUCTION_LENGTH);
wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INST_LENGTH, ins_len);
}
-
+
uint64_t err = 0;
if (idt_info & VMCS_INTR_DEL_ERRCODE) {
err = rvmcs(cpu_state->hvf_fd, VMCS_IDT_VECTORING_ERROR);
wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_EXCEPTION_ERROR, err);
}
- //printf("reinject %lx err %d\n", info, err);
+ /*printf("reinject %lx err %d\n", info, err);*/
wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);
};
}
@@ -408,22 +415,26 @@ void hvf_inject_interrupts(CPUState *cpu_state)
}
}
- if (cpu_state->hvf_x86->interruptable && (cpu_state->interrupt_request & CPU_INTERRUPT_HARD) &&
+ if (cpu_state->hvf_x86->interruptable &&
+ (cpu_state->interrupt_request & CPU_INTERRUPT_HARD) &&
(EFLAGS(cpu_state) & IF_MASK) && !(info & VMCS_INTR_VALID)) {
int line = cpu_get_pic_interrupt(&x86cpu->env);
cpu_state->interrupt_request &= ~CPU_INTERRUPT_HARD;
- if (line >= 0)
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, line | VMCS_INTR_VALID | VMCS_INTR_T_HWINTR);
+ if (line >= 0) {
+ wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, line |
+ VMCS_INTR_VALID | VMCS_INTR_T_HWINTR);
+ }
}
- if (cpu_state->interrupt_request & CPU_INTERRUPT_HARD)
+ if (cpu_state->interrupt_request & CPU_INTERRUPT_HARD) {
vmx_set_int_window_exiting(cpu_state);
+ }
}
int hvf_process_events(CPUState *cpu_state)
{
X86CPU *cpu = X86_CPU(cpu_state);
CPUX86State *env = &cpu->env;
-
+
EFLAGS(cpu_state) = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
@@ -435,7 +446,8 @@ int hvf_process_events(CPUState *cpu_state)
cpu_state->interrupt_request &= ~CPU_INTERRUPT_POLL;
apic_poll_irq(cpu->apic_state);
}
- if (((cpu_state->interrupt_request & CPU_INTERRUPT_HARD) && (EFLAGS(cpu_state) & IF_MASK)) ||
+ if (((cpu_state->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (EFLAGS(cpu_state) & IF_MASK)) ||
(cpu_state->interrupt_request & CPU_INTERRUPT_NMI)) {
cpu_state->halted = 0;
}
@@ -7,7 +7,8 @@ int hvf_process_events(CPUState *);
int hvf_put_registers(CPUState *);
int hvf_get_registers(CPUState *);
void hvf_inject_interrupts(CPUState *);
-void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg, SegmentCache *qseg, bool is_tr);
+void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
+ SegmentCache *qseg, bool is_tr);
void hvf_get_segment(SegmentCache *qseg, struct vmx_segment *vmx_seg);
void hvf_put_xsave(CPUState *cpu_state);
void hvf_put_segments(CPUState *cpu_state);
@@ -16,4 +17,6 @@ void hvf_get_xsave(CPUState *cpu_state);
void hvf_get_msrs(CPUState *cpu_state);
void vmx_clear_int_window_exiting(CPUState *cpu);
void hvf_get_segments(CPUState *cpu_state);
+void vmx_update_tpr(CPUState *cpu);
+void hvf_cpu_synchronize_state(CPUState *cpu_state);
#endif
Signed-off-by: Sergio Andres Gomez Del Real <Sergio.G.DelReal@gmail.com> --- include/sysemu/hvf.h | 22 +- target/i386/hvf-all.c | 793 ++++++------ target/i386/hvf-i386.h | 2 +- target/i386/hvf-utils/vmcs.h | 484 ++++---- target/i386/hvf-utils/vmx.h | 92 +- target/i386/hvf-utils/x86.c | 86 +- target/i386/hvf-utils/x86.h | 112 +- target/i386/hvf-utils/x86_cpuid.c | 337 ++--- target/i386/hvf-utils/x86_cpuid.h | 7 +- target/i386/hvf-utils/x86_decode.c | 2402 ++++++++++++++++++++++-------------- target/i386/hvf-utils/x86_decode.h | 30 +- target/i386/hvf-utils/x86_descr.h | 29 +- target/i386/hvf-utils/x86_emu.c | 1337 ++++++++++---------- target/i386/hvf-utils/x86_emu.h | 15 + target/i386/hvf-utils/x86_flags.c | 52 +- target/i386/hvf-utils/x86_flags.h | 101 +- target/i386/hvf-utils/x86_mmu.c | 85 +- target/i386/hvf-utils/x86_mmu.h | 6 +- target/i386/hvf-utils/x86hvf.c | 106 +- target/i386/hvf-utils/x86hvf.h | 5 +- 20 files changed, 3437 insertions(+), 2666 deletions(-)