* [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 @ 2025-04-23 9:40 Paolo Bonzini 2025-04-23 9:40 ` [PULL 01/34] scsi: add conversion from ENODEV to sense Paolo Bonzini ` (34 more replies) 0 siblings, 35 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel The following changes since commit 8bdd3a0308ba8e8d20240ac06de8615959bcf00e: tests/functional/test_aarch64_replay: reenable on macos (2025-04-14 11:03:16 -0400) are available in the Git repository at: https://gitlab.com/bonzini/qemu.git tags/for-upstream for you to fetch changes up to 6d8c6dee3a767e7650e5d0640e13adb9f01fa37c: rust/hw/char/pl011: Extract DR write logic into separate function (2025-04-23 10:35:23 +0200) ---------------------------------------------------------------- * target/i386: Fix model number of Zhaoxin YongFeng vCPU template * target/i386: Reset parked vCPUs together with the online ones * scsi: add conversion from ENODEV to sense * target/i386: tweaks to flag handling * target/i386: tweaks to SHLD/SHRD code generation * target/i386: remove some global temporaries from TCG * target/i386: pull emulator outside target/i386/hvf * host/i386: consolidate getting host CPU vendor * rust/hpet: preparation for migration support * rust/pl011: bring over more commits from C version ---------------------------------------------------------------- Ewan Hai (1): target/i386: Fix model number of Zhaoxin YongFeng vCPU template Maciej S. Szmigiero (1): target/i386: Reset parked vCPUs together with the online ones Paolo Bonzini (11): scsi: add conversion from ENODEV to sense target/i386/hvf: fix lflags_to_rflags target/i386: special case ADC/SBB x,0 and SBB x,x target/i386: tcg: remove tmp0 and tmp4 from SHLD/SHRD target/i386: tcg: remove subf from SHLD/SHRD expansion target/i386: tcg: remove tmp0 target/i386: tcg: remove some more uses of temporaries target/i386: tcg: simplify computation of AF after INC/DEC target/i386: emulate: microoptimize and explain ADD_COUT_VEC/SUB_COUT_VEC target/i386: tcg: use cout to commonize add/adc/sub/sbb cases target/i386/emulate: remove flags_mask Rakesh Jeyasingh (2): rust/hw/char/pl011: Extract extract DR read logic into separate function rust/hw/char/pl011: Extract DR write logic into separate function Wei Liu (14): target/i386/hvf: introduce x86_emul_ops target/i386/hvf: remove HVF specific calls from x86_decode.c target/i386/hvf: provide and use handle_io in emul_ops target/i386: rename hvf_mmio_buf to emu_mmio_buf target/i386/hvf: use emul_ops->read_mem in x86_emu.c target/i386/hvf: provide and use write_mem in emul_ops target/i386/hvf: provide and use simulate_{wrmsr, rdmsr} in emul_ops target/i386: rename lazy flags field and its type target/i386/hvf: drop unused headers target/i386/hvf: rename some include guards target/i386: add a directory for x86 instruction emulator target/i386/emulate: add a panic.h target/i386: move x86 instruction emulator out of hvf MAINTAINERS: add an entry for the x86 instruction emulator Zhao Liu (5): i386/cpu: Consolidate the helper to get Host's vendor rust/hpet: convert num_timers to u8 type rust/hpet: convert HPETTimer index to u8 type rust/hpet: Fix a clippy error rust/vmstate_test: Fix typo in test_vmstate_macro_array_of_pointer_wrapped() MAINTAINERS | 8 + target/i386/cpu.h | 33 +- target/i386/emulate/panic.h | 45 ++ target/i386/{hvf => emulate}/x86.h | 4 +- target/i386/{hvf => emulate}/x86_decode.h | 6 +- target/i386/{hvf => emulate}/x86_emu.h | 15 +- target/i386/{hvf => emulate}/x86_flags.h | 6 +- target/i386/hvf/hvf-i386.h | 4 +- target/i386/hvf/vmx.h | 2 +- target/i386/hvf/x86_descr.h | 2 +- target/i386/tcg/cc_helper_template.h.inc | 90 +-- accel/kvm/kvm-all.c | 8 +- scsi/utils.c | 13 +- target/i386/cpu.c | 12 + target/i386/{hvf => emulate}/x86_decode.c | 886 +++++++++++++++--------------- target/i386/{hvf => emulate}/x86_emu.c | 62 +-- target/i386/{hvf => emulate}/x86_flags.c | 66 +-- target/i386/host-cpu.c | 10 +- target/i386/hvf/hvf.c | 57 +- target/i386/hvf/x86.c | 4 +- target/i386/hvf/x86_cpuid.c | 2 +- target/i386/hvf/x86_mmu.c | 2 +- target/i386/hvf/x86_task.c | 6 +- target/i386/hvf/x86hvf.c | 2 +- target/i386/kvm/vmsr_energy.c | 3 +- target/i386/tcg/translate.c | 144 +++-- target/i386/tcg/emit.c.inc | 180 ++++-- rust/hw/char/pl011/src/device.rs | 53 +- rust/hw/timer/hpet/src/hpet.rs | 43 +- rust/qemu-api/tests/vmstate_tests.rs | 4 +- target/i386/emulate/meson.build | 5 + target/i386/hvf/meson.build | 3 - target/i386/meson.build | 1 + 33 files changed, 989 insertions(+), 792 deletions(-) create mode 100644 target/i386/emulate/panic.h rename target/i386/{hvf => emulate}/x86.h (99%) rename target/i386/{hvf => emulate}/x86_decode.h (99%) rename target/i386/{hvf => emulate}/x86_emu.h (75%) rename target/i386/{hvf => emulate}/x86_flags.h (97%) rename target/i386/{hvf => emulate}/x86_decode.c (71%) rename target/i386/{hvf => emulate}/x86_emu.c (95%) rename target/i386/{hvf => emulate}/x86_flags.c (80%) create mode 100644 target/i386/emulate/meson.build -- 2.49.0 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PULL 01/34] scsi: add conversion from ENODEV to sense 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 02/34] target/i386: Fix model number of Zhaoxin YongFeng vCPU template Paolo Bonzini ` (33 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel This is mostly for completeness; I noticed it because ENODEV is used internally within scsi-disk.c, but when scsi_sense_from_errno(ENODEV) is called the resulting sense is never used and instead scsi_sense_from_host_status() is called later by scsi_req_complete_failed(). Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- scsi/utils.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scsi/utils.c b/scsi/utils.c index 357b0366716..545956f4f95 100644 --- a/scsi/utils.c +++ b/scsi/utils.c @@ -587,20 +587,27 @@ int scsi_sense_from_errno(int errno_value, SCSISense *sense) return GOOD; case EDOM: return TASK_SET_FULL; +#if ENODEV != ENOMEDIUM + case ENODEV: + /* + * Some of the BSDs have ENODEV and ENOMEDIUM as synonyms. For + * everyone else, give a more severe sense code for ENODEV. + */ +#endif #ifdef CONFIG_LINUX /* These errno mapping are specific to Linux. For more information: * - scsi_check_sense and scsi_decide_disposition in drivers/scsi/scsi_error.c * - scsi_result_to_blk_status in drivers/scsi/scsi_lib.c * - blk_errors[] in block/blk-core.c */ + case EREMOTEIO: + *sense = SENSE_CODE(TARGET_FAILURE); + return CHECK_CONDITION; case EBADE: return RESERVATION_CONFLICT; case ENODATA: *sense = SENSE_CODE(READ_ERROR); return CHECK_CONDITION; - case EREMOTEIO: - *sense = SENSE_CODE(TARGET_FAILURE); - return CHECK_CONDITION; #endif case ENOMEDIUM: *sense = SENSE_CODE(NO_MEDIUM); -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 02/34] target/i386: Fix model number of Zhaoxin YongFeng vCPU template 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini 2025-04-23 9:40 ` [PULL 01/34] scsi: add conversion from ENODEV to sense Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 03/34] target/i386: Reset parked vCPUs together with the online ones Paolo Bonzini ` (32 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Ewan Hai From: Ewan Hai <ewanhai-oc@zhaoxin.com> The model number was mistakenly set to 0x0b (11) in commit ff04bc1ac4. The correct value is 0x5b. This mistake occurred because the extended model bits in cpuid[eax=0x1].eax were overlooked, and only the base model was used. Using the wrong model number can affect guest behavior. One known issue is that vPMU (which relies on the model number) may fail to operate correctly. This patch corrects the model field by introducing a new vCPU version. Fixes: ff04bc1ac4 ("target/i386: Introduce Zhaoxin Yongfeng CPU model") Signed-off-by: Ewan Hai <ewanhai-oc@zhaoxin.com> Link: https://lore.kernel.org/r/20250414075342.411626-1-ewanhai-oc@zhaoxin.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/cpu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 1b64ceaaba4..3fb1ec62da1 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5621,6 +5621,18 @@ static const X86CPUDefinition builtin_x86_defs[] = { .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING, .xlevel = 0x80000008, .model_id = "Zhaoxin YongFeng Processor", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .note = "with the correct model number", + .props = (PropValue[]) { + { "model", "0x5b" }, + { /* end of list */ } + } + }, + { /* end of list */ } + } }, }; -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 03/34] target/i386: Reset parked vCPUs together with the online ones 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini 2025-04-23 9:40 ` [PULL 01/34] scsi: add conversion from ENODEV to sense Paolo Bonzini 2025-04-23 9:40 ` [PULL 02/34] target/i386: Fix model number of Zhaoxin YongFeng vCPU template Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 04/34] target/i386/hvf: fix lflags_to_rflags Paolo Bonzini ` (31 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Maciej S. Szmigiero, qemu-stable From: "Maciej S. Szmigiero" <maciej.szmigiero@oracle.com> Commit 3f2a05b31ee9 ("target/i386: Reset TSCs of parked vCPUs too on VM reset") introduced a way to reset TSCs of parked vCPUs during VM reset to prevent them getting desynchronized with the online vCPUs and therefore causing the KVM PV clock to lose PVCLOCK_TSC_STABLE_BIT. The way this was done was by registering a parked vCPU-specific QEMU reset callback via qemu_register_reset(). However, it turns out that on particularly device-rich VMs QEMU reset callbacks can take a long time to execute (which isn't surprising, considering that they involve resetting all of VM devices). In particular, their total runtime can exceed the 1-second TSC synchronization window introduced in KVM commit 5d3cb0f6a8e3 ("KVM: Improve TSC offset matching"). Since the TSCs of online vCPUs are only reset from "synchronize_post_reset" AccelOps handler (which runs after all qemu_register_reset() handlers) this essentially makes that fix ineffective on these VMs. The easiest way to guarantee that these parked vCPUs are reset at the same time as the online ones (regardless how long it takes for VM devices to reset) is to piggyback on post-reset vCPU synchronization handler for one of online vCPUs - as there is no generic post-reset AccelOps handler that isn't per-vCPU. The first online vCPU was selected for that since it is easily available under "first_cpu" define. This does not create an ordering issue since the order of vCPU TSC resets does not matter. Fixes: 3f2a05b31ee9 ("target/i386: Reset TSCs of parked vCPUs too on VM reset") Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com> Link: https://lore.kernel.org/r/e8b85a5915f79aa177ca49eccf0e9b534470c1cd.1743099810.git.maciej.szmigiero@oracle.com Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- accel/kvm/kvm-all.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index f89568bfa39..951e8214e07 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -437,9 +437,8 @@ int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id) return kvm_fd; } -static void kvm_reset_parked_vcpus(void *param) +static void kvm_reset_parked_vcpus(KVMState *s) { - KVMState *s = param; struct KVMParkedVcpu *cpu; QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) { @@ -2738,7 +2737,6 @@ static int kvm_init(MachineState *ms) } qemu_register_reset(kvm_unpoison_all, NULL); - qemu_register_reset(kvm_reset_parked_vcpus, s); if (s->kernel_irqchip_allowed) { kvm_irqchip_create(s); @@ -2908,6 +2906,10 @@ static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg void kvm_cpu_synchronize_post_reset(CPUState *cpu) { run_on_cpu(cpu, do_kvm_cpu_synchronize_post_reset, RUN_ON_CPU_NULL); + + if (cpu == first_cpu) { + kvm_reset_parked_vcpus(kvm_state); + } } static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 04/34] target/i386/hvf: fix lflags_to_rflags 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (2 preceding siblings ...) 2025-04-23 9:40 ` [PULL 03/34] target/i386: Reset parked vCPUs together with the online ones Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 05/34] target/i386: special case ADC/SBB x,0 and SBB x,x Paolo Bonzini ` (30 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu, qemu-stable, Philippe Mathieu-Daudé Clear the flags before adding in the ones computed from lflags. Cc: Wei Liu <liuwe@linux.microsoft.com> Cc: qemu-stable@nongnu.org Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86_flags.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/i386/hvf/x86_flags.c b/target/i386/hvf/x86_flags.c index 03d6de5efc3..fedc70a1b80 100644 --- a/target/i386/hvf/x86_flags.c +++ b/target/i386/hvf/x86_flags.c @@ -293,6 +293,7 @@ void set_SF(CPUX86State *env, bool val) void lflags_to_rflags(CPUX86State *env) { + env->eflags &= ~(CC_C|CC_P|CC_A|CC_Z|CC_S|CC_O); env->eflags |= get_CF(env) ? CC_C : 0; env->eflags |= get_PF(env) ? CC_P : 0; env->eflags |= get_AF(env) ? CC_A : 0; -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 05/34] target/i386: special case ADC/SBB x,0 and SBB x,x 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (3 preceding siblings ...) 2025-04-23 9:40 ` [PULL 04/34] target/i386/hvf: fix lflags_to_rflags Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 06/34] target/i386: tcg: remove tmp0 and tmp4 from SHLD/SHRD Paolo Bonzini ` (29 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel Avoid the three-operand CC_OP_ADD and CC_OP_ADC in these relatively common cases. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/tcg/translate.c | 20 +++++++++++ target/i386/tcg/emit.c.inc | 71 +++++++++++++++++++++++++++++++++---- 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index a8935f487aa..aee33428989 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -1183,6 +1183,26 @@ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg) return cc; } +static void gen_neg_setcc(DisasContext *s, int b, TCGv reg) +{ + CCPrepare cc = gen_prepare_cc(s, b, reg); + + if (cc.no_setcond) { + if (cc.cond == TCG_COND_EQ) { + tcg_gen_addi_tl(reg, cc.reg, -1); + } else { + tcg_gen_neg_tl(reg, cc.reg); + } + return; + } + + if (cc.use_reg2) { + tcg_gen_negsetcond_tl(cc.cond, reg, cc.reg, cc.reg2); + } else { + tcg_gen_negsetcondi_tl(cc.cond, reg, cc.reg, cc.imm); + } +} + static void gen_setcc(DisasContext *s, int b, TCGv reg) { CCPrepare cc = gen_prepare_cc(s, b, reg); diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index 0fa1664a24f..f477a2da992 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -1170,11 +1170,28 @@ static void gen_AAS(DisasContext *s, X86DecodedInsn *decode) assume_cc_op(s, CC_OP_EFLAGS); } +static void gen_ADD(DisasContext *s, X86DecodedInsn *decode); static void gen_ADC(DisasContext *s, X86DecodedInsn *decode) { MemOp ot = decode->op[1].ot; - TCGv c_in = tcg_temp_new(); + TCGv c_in; + /* + * Try to avoid CC_OP_ADC by transforming as follows: + * CC_ADC: src1 = dst + c_in, src2 = 0, src3 = c_in + * CC_ADD: src1 = dst + c_in, src2 = c_in (no src3) + * + * In general src2 vs. src3 matters when computing AF and OF, but not here: + * - AF is bit 4 of dst^src1^src2, which is bit 4 of dst^src1 in both cases + * - OF is a function of the two MSBs, and in both cases they are zero for src2 + */ + if (decode->e.op2 == X86_TYPE_I && decode->immediate == 0) { + gen_compute_eflags_c(s, s->T1); + gen_ADD(s, decode); + return; + } + + c_in = tcg_temp_new(); gen_compute_eflags_c(s, c_in); if (s->prefix & PREFIX_LOCK) { tcg_gen_add_tl(s->T0, c_in, s->T1); @@ -3830,22 +3847,64 @@ static void gen_SARX(DisasContext *s, X86DecodedInsn *decode) tcg_gen_sar_tl(s->T0, s->T0, s->T1); } +static void gen_SUB(DisasContext *s, X86DecodedInsn *decode); static void gen_SBB(DisasContext *s, X86DecodedInsn *decode) { MemOp ot = decode->op[0].ot; - TCGv c_in = tcg_temp_new(); + TCGv c_in; + /* + * Try to avoid CC_OP_SBB by transforming as follows: + * CC_SBB: src1 = dst + c_in, src2 = 0, src3 = c_in + * CC_SUB: src1 = dst + c_in, src2 = c_in (no src3) + * + * In general src2 vs. src3 matters when computing AF and OF, but not here: + * - AF is bit 4 of dst^src1^src2, which is bit 4 of dst^src1 in both cases + * - OF is a function of the two MSBs, and in both cases they are zero for src2 + */ + if (decode->e.op2 == X86_TYPE_I && decode->immediate == 0) { + gen_compute_eflags_c(s, s->T1); + gen_SUB(s, decode); + return; + } + + c_in = tcg_temp_new(); gen_compute_eflags_c(s, c_in); + + /* + * Here the change is as follows: + * CC_SBB: src1 = T0, src2 = T0, src3 = c_in + * CC_SUB: src1 = 0, src2 = c_in (no src3) + * + * The difference also does not matter: + * - AF is bit 4 of dst^src1^src2, but bit 4 of src1^src2 is zero in both cases + * therefore AF comes straight from dst (in fact it is c_in) + * - for OF, src1 and src2 have the same sign in both cases, meaning there + * can be no overflow + */ + if (decode->e.op2 != X86_TYPE_I && !decode->op[0].has_ea && decode->op[0].n == decode->op[2].n) { + if (s->cc_op == CC_OP_DYNAMIC) { + tcg_gen_neg_tl(s->T0, c_in); + } else { + /* + * Do not negate c_in because it will often be dead and only the + * instruction generated by negsetcond will survive. + */ + gen_neg_setcc(s, JCC_B << 1, s->T0); + } + tcg_gen_movi_tl(s->cc_srcT, 0); + decode->cc_src = c_in; + decode->cc_dst = s->T0; + decode->cc_op = CC_OP_SUBB + ot; + return; + } + if (s->prefix & PREFIX_LOCK) { tcg_gen_add_tl(s->T0, s->T1, c_in); tcg_gen_neg_tl(s->T0, s->T0); tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T0, s->mem_index, ot | MO_LE); } else { - /* - * TODO: SBB reg, reg could use gen_prepare_eflags_c followed by - * negsetcond, and CC_OP_SUBB as the cc_op. - */ tcg_gen_sub_tl(s->T0, s->T0, s->T1); tcg_gen_sub_tl(s->T0, s->T0, c_in); } -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 06/34] target/i386: tcg: remove tmp0 and tmp4 from SHLD/SHRD 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (4 preceding siblings ...) 2025-04-23 9:40 ` [PULL 05/34] target/i386: special case ADC/SBB x,0 and SBB x,x Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 07/34] target/i386: tcg: remove subf from SHLD/SHRD expansion Paolo Bonzini ` (28 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel Apply some of the simplifications used for RCL and RCR. tmp4 is not used anywhere else, so remove it. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/tcg/translate.c | 51 +++++++++++++++++++++---------------- target/i386/tcg/emit.c.inc | 6 ++--- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index aee33428989..5529327680d 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -135,7 +135,6 @@ typedef struct DisasContext { /* TCG local register indexes (only used inside old micro ops) */ TCGv tmp0; - TCGv tmp4; TCGv_i32 tmp2_i32; TCGv_i32 tmp3_i32; TCGv_i64 tmp1_i64; @@ -1580,10 +1579,13 @@ static bool check_cpl0(DisasContext *s) } /* XXX: add faster immediate case */ -static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, +static TCGv gen_shiftd_rm_T1(DisasContext *s, MemOp ot, bool is_right, TCGv count) { target_ulong mask = (ot == MO_64 ? 63 : 31); + TCGv cc_src = tcg_temp_new(); + TCGv tmp = tcg_temp_new(); + TCGv hishift; switch (ot) { case MO_16: @@ -1591,9 +1593,9 @@ static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A portion by constructing it as a 32-bit value. */ if (is_right) { - tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16); + tcg_gen_deposit_tl(tmp, s->T0, s->T1, 16, 16); tcg_gen_mov_tl(s->T1, s->T0); - tcg_gen_mov_tl(s->T0, s->tmp0); + tcg_gen_mov_tl(s->T0, tmp); } else { tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16); } @@ -1604,47 +1606,53 @@ static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, case MO_32: #ifdef TARGET_X86_64 /* Concatenate the two 32-bit values and use a 64-bit shift. */ - tcg_gen_subi_tl(s->tmp0, count, 1); + tcg_gen_subi_tl(tmp, count, 1); if (is_right) { tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1); - tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0); + tcg_gen_shr_i64(cc_src, s->T0, tmp); tcg_gen_shr_i64(s->T0, s->T0, count); } else { tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0); - tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0); + tcg_gen_shl_i64(cc_src, s->T0, tmp); tcg_gen_shl_i64(s->T0, s->T0, count); - tcg_gen_shri_i64(s->tmp0, s->tmp0, 32); + tcg_gen_shri_i64(cc_src, cc_src, 32); tcg_gen_shri_i64(s->T0, s->T0, 32); } break; #endif default: - tcg_gen_subi_tl(s->tmp0, count, 1); + hishift = tcg_temp_new(); + tcg_gen_subi_tl(tmp, count, 1); if (is_right) { - tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0); + tcg_gen_shr_tl(cc_src, s->T0, tmp); - tcg_gen_subfi_tl(s->tmp4, mask + 1, count); + /* mask + 1 - count = mask - tmp = mask ^ tmp */ + tcg_gen_xori_tl(hishift, tmp, mask); tcg_gen_shr_tl(s->T0, s->T0, count); - tcg_gen_shl_tl(s->T1, s->T1, s->tmp4); + tcg_gen_shl_tl(s->T1, s->T1, hishift); } else { - tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0); + tcg_gen_shl_tl(cc_src, s->T0, tmp); + if (ot == MO_16) { /* Only needed if count > 16, for Intel behaviour. */ - tcg_gen_subfi_tl(s->tmp4, 33, count); - tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4); - tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4); + tcg_gen_subfi_tl(tmp, 33, count); + tcg_gen_shr_tl(tmp, s->T1, tmp); + tcg_gen_or_tl(cc_src, cc_src, tmp); } - tcg_gen_subfi_tl(s->tmp4, mask + 1, count); + /* mask + 1 - count = mask - tmp = mask ^ tmp */ + tcg_gen_xori_tl(hishift, tmp, mask); tcg_gen_shl_tl(s->T0, s->T0, count); - tcg_gen_shr_tl(s->T1, s->T1, s->tmp4); + tcg_gen_shr_tl(s->T1, s->T1, hishift); } - tcg_gen_movi_tl(s->tmp4, 0); - tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4, - s->tmp4, s->T1); + tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, + count, tcg_constant_tl(0), + tcg_constant_tl(0), s->T1); tcg_gen_or_tl(s->T0, s->T0, s->T1); break; } + + return cc_src; } #define X86_MAX_INSN_LENGTH 15 @@ -3768,7 +3776,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) dc->tmp1_i64 = tcg_temp_new_i64(); dc->tmp2_i32 = tcg_temp_new_i32(); dc->tmp3_i32 = tcg_temp_new_i32(); - dc->tmp4 = tcg_temp_new(); dc->cc_srcT = tcg_temp_new(); } diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index f477a2da992..a41afb7fe46 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -4015,8 +4015,7 @@ static void gen_SHLD(DisasContext *s, X86DecodedInsn *decode) } decode->cc_dst = s->T0; - decode->cc_src = s->tmp0; - gen_shiftd_rm_T1(s, ot, false, count); + decode->cc_src = gen_shiftd_rm_T1(s, ot, false, count); if (can_be_zero) { gen_shift_dynamic_flags(s, decode, count, CC_OP_SHLB + ot); } else { @@ -4068,8 +4067,7 @@ static void gen_SHRD(DisasContext *s, X86DecodedInsn *decode) } decode->cc_dst = s->T0; - decode->cc_src = s->tmp0; - gen_shiftd_rm_T1(s, ot, true, count); + decode->cc_src = gen_shiftd_rm_T1(s, ot, true, count); if (can_be_zero) { gen_shift_dynamic_flags(s, decode, count, CC_OP_SARB + ot); } else { -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 07/34] target/i386: tcg: remove subf from SHLD/SHRD expansion 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (5 preceding siblings ...) 2025-04-23 9:40 ` [PULL 06/34] target/i386: tcg: remove tmp0 and tmp4 from SHLD/SHRD Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 08/34] target/i386: tcg: remove tmp0 Paolo Bonzini ` (27 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel It is computing 33-count but 32-count had just been used, so just shift further by one. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/tcg/translate.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 5529327680d..822dbb2e9ae 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -1633,17 +1633,16 @@ static TCGv gen_shiftd_rm_T1(DisasContext *s, MemOp ot, } else { tcg_gen_shl_tl(cc_src, s->T0, tmp); - if (ot == MO_16) { - /* Only needed if count > 16, for Intel behaviour. */ - tcg_gen_subfi_tl(tmp, 33, count); - tcg_gen_shr_tl(tmp, s->T1, tmp); - tcg_gen_or_tl(cc_src, cc_src, tmp); - } - /* mask + 1 - count = mask - tmp = mask ^ tmp */ tcg_gen_xori_tl(hishift, tmp, mask); tcg_gen_shl_tl(s->T0, s->T0, count); tcg_gen_shr_tl(s->T1, s->T1, hishift); + + if (ot == MO_16) { + /* Only needed if count > 16, for Intel behaviour. */ + tcg_gen_shri_tl(tmp, s->T1, 1); + tcg_gen_or_tl(cc_src, cc_src, tmp); + } } tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, tcg_constant_tl(0), -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 08/34] target/i386: tcg: remove tmp0 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (6 preceding siblings ...) 2025-04-23 9:40 ` [PULL 07/34] target/i386: tcg: remove subf from SHLD/SHRD expansion Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 09/34] target/i386: tcg: remove some more uses of temporaries Paolo Bonzini ` (26 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/tcg/translate.c | 27 +++++++++++++++------------ target/i386/tcg/emit.c.inc | 20 ++++++++++---------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 822dbb2e9ae..5d433f8522e 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -134,7 +134,6 @@ typedef struct DisasContext { TCGv T1; /* TCG local register indexes (only used inside old micro ops) */ - TCGv tmp0; TCGv_i32 tmp2_i32; TCGv_i32 tmp3_i32; TCGv_i64 tmp1_i64; @@ -2175,14 +2174,17 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) level &= 31; if (level != 0) { int i; + if (level > 1) { + TCGv fp = tcg_temp_new(); - /* Copy level-1 pointers from the previous frame. */ - for (i = 1; i < level; ++i) { - gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], -size * i); - gen_op_ld_v(s, d_ot, s->tmp0, s->A0); + /* Copy level-1 pointers from the previous frame. */ + for (i = 1; i < level; ++i) { + gen_lea_ss_ofs(s, s->A0, cpu_regs[R_EBP], -size * i); + gen_op_ld_v(s, d_ot, fp, s->A0); - gen_lea_ss_ofs(s, s->A0, s->T1, -size * i); - gen_op_st_v(s, d_ot, s->tmp0, s->A0); + gen_lea_ss_ofs(s, s->A0, s->T1, -size * i); + gen_op_st_v(s, d_ot, fp, s->A0); + } } /* Push the current FrameTemp as the last level. */ @@ -2405,10 +2407,11 @@ static void gen_ldy_env_A0(DisasContext *s, int offset, bool align) int mem_index = s->mem_index; TCGv_i128 t0 = tcg_temp_new_i128(); TCGv_i128 t1 = tcg_temp_new_i128(); + TCGv a0_hi = tcg_temp_new(); tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); - tcg_gen_addi_tl(s->tmp0, s->A0, 16); - tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop); + tcg_gen_addi_tl(a0_hi, s->A0, 16); + tcg_gen_qemu_ld_i128(t1, a0_hi, mem_index, mop); tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); @@ -2419,12 +2422,13 @@ static void gen_sty_env_A0(DisasContext *s, int offset, bool align) MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR; int mem_index = s->mem_index; TCGv_i128 t = tcg_temp_new_i128(); + TCGv a0_hi = tcg_temp_new(); tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0))); tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0)); - tcg_gen_addi_tl(s->tmp0, s->A0, 16); + tcg_gen_addi_tl(a0_hi, s->A0, 16); tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1))); - tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop); + tcg_gen_qemu_st_i128(t, a0_hi, mem_index, mop); } #include "emit.c.inc" @@ -3771,7 +3775,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) dc->T1 = tcg_temp_new(); dc->A0 = tcg_temp_new(); - dc->tmp0 = tcg_temp_new(); dc->tmp1_i64 = tcg_temp_new_i64(); dc->tmp2_i32 = tcg_temp_new_i32(); dc->tmp3_i32 = tcg_temp_new_i32(); diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index a41afb7fe46..bd24438230d 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -1710,22 +1710,22 @@ static void gen_CMPccXADD(DisasContext *s, X86DecodedInsn *decode) switch (jcc_op) { case JCC_O: /* (src1 ^ src2) & (src1 ^ dst). newv is only used here for a moment */ + cmp_lhs = tcg_temp_new(), cmp_rhs = tcg_constant_tl(0); tcg_gen_xor_tl(newv, s->cc_srcT, s->T0); - tcg_gen_xor_tl(s->tmp0, s->cc_srcT, cmpv); - tcg_gen_and_tl(s->tmp0, s->tmp0, newv); - tcg_gen_sextract_tl(s->tmp0, s->tmp0, 0, 8 << ot); - cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(0); + tcg_gen_xor_tl(cmp_lhs, s->cc_srcT, cmpv); + tcg_gen_and_tl(cmp_lhs, cmp_lhs, newv); + tcg_gen_sextract_tl(cmp_lhs, cmp_lhs, 0, 8 << ot); break; case JCC_P: - tcg_gen_ext8u_tl(s->tmp0, s->T0); - tcg_gen_ctpop_tl(s->tmp0, s->tmp0); - cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(1); + cmp_lhs = tcg_temp_new(), cmp_rhs = tcg_constant_tl(1); + tcg_gen_ext8u_tl(cmp_lhs, s->T0); + tcg_gen_ctpop_tl(cmp_lhs, cmp_lhs); break; case JCC_S: - tcg_gen_sextract_tl(s->tmp0, s->T0, 0, 8 << ot); - cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(0); + cmp_lhs = tcg_temp_new(), cmp_rhs = tcg_constant_tl(0); + tcg_gen_sextract_tl(cmp_lhs, s->T0, 0, 8 << ot); break; default: @@ -1876,7 +1876,7 @@ static void gen_CMPXCHG8B(DisasContext *s, X86DecodedInsn *decode) s->mem_index, MO_TEUQ); } - /* Set tmp0 to match the required value of Z. */ + /* Compute the required value of Z. */ tcg_gen_setcond_i64(TCG_COND_EQ, cmp, old, cmp); Z = tcg_temp_new(); tcg_gen_trunc_i64_tl(Z, cmp); -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 09/34] target/i386: tcg: remove some more uses of temporaries 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (7 preceding siblings ...) 2025-04-23 9:40 ` [PULL 08/34] target/i386: tcg: remove tmp0 Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 10/34] target/i386: tcg: simplify computation of AF after INC/DEC Paolo Bonzini ` (25 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel Remove all uses of 32-bit temporaries in emit.c.inc. Remove uses in translate.c outside the large multiplexed generator functions. tmp3_i32 is not used anymore and can go away. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/tcg/translate.c | 43 +++++++++++-------- target/i386/tcg/emit.c.inc | 83 +++++++++++++++++++++++-------------- 2 files changed, 77 insertions(+), 49 deletions(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 5d433f8522e..abe210cc4ef 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -135,7 +135,6 @@ typedef struct DisasContext { /* TCG local register indexes (only used inside old micro ops) */ TCGv_i32 tmp2_i32; - TCGv_i32 tmp3_i32; TCGv_i64 tmp1_i64; sigjmp_buf jmpbuf; @@ -1318,30 +1317,35 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot) static void gen_ins(DisasContext *s, MemOp ot, TCGv dshift) { + TCGv_i32 port = tcg_temp_new_i32(); + gen_string_movl_A0_EDI(s); /* Note: we must do this dummy write first to be restartable in case of page fault. */ tcg_gen_movi_tl(s->T0, 0); gen_op_st_v(s, ot, s->T0, s->A0); - tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); - tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); - gen_helper_in_func(ot, s->T0, s->tmp2_i32); + tcg_gen_trunc_tl_i32(port, cpu_regs[R_EDX]); + tcg_gen_andi_i32(port, port, 0xffff); + gen_helper_in_func(ot, s->T0, port); gen_op_st_v(s, ot, s->T0, s->A0); gen_op_add_reg(s, s->aflag, R_EDI, dshift); - gen_bpt_io(s, s->tmp2_i32, ot); + gen_bpt_io(s, port, ot); } static void gen_outs(DisasContext *s, MemOp ot, TCGv dshift) { + TCGv_i32 port = tcg_temp_new_i32(); + TCGv_i32 value = tcg_temp_new_i32(); + gen_string_movl_A0_ESI(s); gen_op_ld_v(s, ot, s->T0, s->A0); - tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]); - tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff); - tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0); - gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32); + tcg_gen_trunc_tl_i32(port, cpu_regs[R_EDX]); + tcg_gen_andi_i32(port, port, 0xffff); + tcg_gen_trunc_tl_i32(value, s->T0); + gen_helper_out_func(ot, port, value); gen_op_add_reg(s, s->aflag, R_ESI, dshift); - gen_bpt_io(s, s->tmp2_i32, ot); + gen_bpt_io(s, port, ot); } #define REP_MAX 65535 @@ -1869,14 +1873,16 @@ static void gen_bndck(DisasContext *s, X86DecodedInsn *decode, TCGCond cond, TCGv_i64 bndv) { TCGv ea = gen_lea_modrm_1(s, decode->mem, false); + TCGv_i32 t32 = tcg_temp_new_i32(); + TCGv_i64 t64 = tcg_temp_new_i64(); - tcg_gen_extu_tl_i64(s->tmp1_i64, ea); + tcg_gen_extu_tl_i64(t64, ea); if (!CODE64(s)) { - tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64); + tcg_gen_ext32u_i64(t64, t64); } - tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv); - tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64); - gen_helper_bndck(tcg_env, s->tmp2_i32); + tcg_gen_setcond_i64(cond, t64, t64, bndv); + tcg_gen_extrl_i64_i32(t32, t64); + gen_helper_bndck(tcg_env, t32); } /* generate modrm load of memory or register. */ @@ -2021,8 +2027,10 @@ static void gen_op_movl_seg_real(DisasContext *s, X86Seg seg_reg, TCGv seg) static void gen_movl_seg(DisasContext *s, X86Seg seg_reg, TCGv src) { if (PE(s) && !VM86(s)) { - tcg_gen_trunc_tl_i32(s->tmp2_i32, src); - gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32); + TCGv_i32 sel = tcg_temp_new_i32(); + + tcg_gen_trunc_tl_i32(sel, src); + gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), sel); /* abort translation because the addseg value may change or because ss32 may change. For R_SS, translation must always stop as a special handling must be done to disable hardware @@ -3777,7 +3785,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) dc->tmp1_i64 = tcg_temp_new_i64(); dc->tmp2_i32 = tcg_temp_new_i32(); - dc->tmp3_i32 = tcg_temp_new_i32(); dc->cc_srcT = tcg_temp_new(); } diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index bd24438230d..4e09e96fc13 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -1916,9 +1916,10 @@ static void gen_CPUID(DisasContext *s, X86DecodedInsn *decode) static void gen_CRC32(DisasContext *s, X86DecodedInsn *decode) { MemOp ot = decode->op[2].ot; + TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); - gen_helper_crc32(s->T0, s->tmp2_i32, s->T1, tcg_constant_i32(8 << ot)); + tcg_gen_trunc_tl_i32(tmp, s->T0); + gen_helper_crc32(s->T0, tmp, s->T1, tcg_constant_i32(8 << ot)); } static void gen_CVTPI2Px(DisasContext *s, X86DecodedInsn *decode) @@ -2376,8 +2377,10 @@ static void gen_LAR(DisasContext *s, X86DecodedInsn *decode) static void gen_LDMXCSR(DisasContext *s, X86DecodedInsn *decode) { - tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); - gen_helper_ldmxcsr(tcg_env, s->tmp2_i32); + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_trunc_tl_i32(tmp, s->T0); + gen_helper_ldmxcsr(tcg_env, tmp); } static void gen_lxx_seg(DisasContext *s, X86DecodedInsn *decode, int seg) @@ -2590,11 +2593,13 @@ static void gen_MOVDQ(DisasContext *s, X86DecodedInsn *decode) static void gen_MOVMSK(DisasContext *s, X86DecodedInsn *decode) { typeof(gen_helper_movmskps_ymm) *ps, *pd, *fn; + TCGv_i32 tmp = tcg_temp_new_i32(); + ps = s->vex_l ? gen_helper_movmskps_ymm : gen_helper_movmskps_xmm; pd = s->vex_l ? gen_helper_movmskpd_ymm : gen_helper_movmskpd_xmm; fn = s->prefix & PREFIX_DATA ? pd : ps; - fn(s->tmp2_i32, tcg_env, OP_PTR2); - tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); + fn(tmp, tcg_env, OP_PTR2); + tcg_gen_extu_i32_tl(s->T0, tmp); } static void gen_MOVQ(DisasContext *s, X86DecodedInsn *decode) @@ -2691,13 +2696,17 @@ static void gen_MULX(DisasContext *s, X86DecodedInsn *decode) switch (ot) { case MO_32: #ifdef TARGET_X86_64 - tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); - tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1); - tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32, - s->tmp2_i32, s->tmp3_i32); - tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], s->tmp2_i32); - tcg_gen_extu_i32_tl(s->T0, s->tmp3_i32); - break; + { + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i32 t1 = tcg_temp_new_i32(); + + tcg_gen_trunc_tl_i32(t0, s->T0); + tcg_gen_trunc_tl_i32(t1, s->T1); + tcg_gen_mulu2_i32(t0, t1, t0, t1); + tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], t0); + tcg_gen_extu_i32_tl(s->T0, t1); + break; + } case MO_64: #endif @@ -3741,10 +3750,14 @@ static void gen_RORX(DisasContext *s, X86DecodedInsn *decode) switch (ot) { case MO_32: #ifdef TARGET_X86_64 - tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0); - tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, b); - tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32); - break; + { + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_trunc_tl_i32(tmp, s->T0); + tcg_gen_rotri_i32(tmp, tmp, b); + tcg_gen_extu_i32_tl(s->T0, tmp); + break; + } case MO_64: #endif @@ -4334,7 +4347,7 @@ static void gen_VCVTSI2Sx(DisasContext *s, X86DecodedInsn *decode) } return; } - in = s->tmp2_i32; + in = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(in, s->T1); #else in = s->T1; @@ -4364,7 +4377,7 @@ static inline void gen_VCVTtSx2SI(DisasContext *s, X86DecodedInsn *decode, return; } - out = s->tmp2_i32; + out = tcg_temp_new_i32(); #else out = s->T0; #endif @@ -4416,7 +4429,7 @@ static void gen_VEXTRACTPS(DisasContext *s, X86DecodedInsn *decode) gen_pextr(s, decode, MO_32); } -static void gen_vinsertps(DisasContext *s, X86DecodedInsn *decode) +static void gen_vinsertps(DisasContext *s, X86DecodedInsn *decode, TCGv_i32 tmp) { int val = decode->immediate; int dest_word = (val >> 4) & 3; @@ -4433,7 +4446,7 @@ static void gen_vinsertps(DisasContext *s, X86DecodedInsn *decode) } if (new_mask != (val & 15)) { - tcg_gen_st_i32(s->tmp2_i32, tcg_env, + tcg_gen_st_i32(tmp, tcg_env, vector_elem_offset(&decode->op[0], MO_32, dest_word)); } @@ -4452,15 +4465,19 @@ static void gen_vinsertps(DisasContext *s, X86DecodedInsn *decode) static void gen_VINSERTPS_r(DisasContext *s, X86DecodedInsn *decode) { int val = decode->immediate; - tcg_gen_ld_i32(s->tmp2_i32, tcg_env, + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_ld_i32(tmp, tcg_env, vector_elem_offset(&decode->op[2], MO_32, (val >> 6) & 3)); - gen_vinsertps(s, decode); + gen_vinsertps(s, decode, tmp); } static void gen_VINSERTPS_m(DisasContext *s, X86DecodedInsn *decode) { - tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL); - gen_vinsertps(s, decode); + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_qemu_ld_i32(tmp, s->A0, s->mem_index, MO_LEUL); + gen_vinsertps(s, decode, tmp); } static void gen_VINSERTx128(DisasContext *s, X86DecodedInsn *decode) @@ -4581,25 +4598,29 @@ static void gen_VMOVSD_ld(DisasContext *s, X86DecodedInsn *decode) static void gen_VMOVSS(DisasContext *s, X86DecodedInsn *decode) { int vec_len = vector_len(s, decode); + TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_ld_i32(s->tmp2_i32, OP_PTR2, offsetof(ZMMReg, ZMM_L(0))); + tcg_gen_ld_i32(tmp, OP_PTR2, offsetof(ZMMReg, ZMM_L(0))); tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len); - tcg_gen_st_i32(s->tmp2_i32, OP_PTR0, offsetof(ZMMReg, ZMM_L(0))); + tcg_gen_st_i32(tmp, OP_PTR0, offsetof(ZMMReg, ZMM_L(0))); } static void gen_VMOVSS_ld(DisasContext *s, X86DecodedInsn *decode) { int vec_len = vector_len(s, decode); + TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL); + tcg_gen_qemu_ld_i32(tmp, s->A0, s->mem_index, MO_LEUL); tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0); - tcg_gen_st_i32(s->tmp2_i32, OP_PTR0, offsetof(ZMMReg, ZMM_L(0))); + tcg_gen_st_i32(tmp, OP_PTR0, offsetof(ZMMReg, ZMM_L(0))); } static void gen_VMOVSS_st(DisasContext *s, X86DecodedInsn *decode) { - tcg_gen_ld_i32(s->tmp2_i32, OP_PTR2, offsetof(ZMMReg, ZMM_L(0))); - tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL); + TCGv_i32 tmp = tcg_temp_new_i32(); + + tcg_gen_ld_i32(tmp, OP_PTR2, offsetof(ZMMReg, ZMM_L(0))); + tcg_gen_qemu_st_i32(tmp, s->A0, s->mem_index, MO_LEUL); } static void gen_VPMASKMOV_st(DisasContext *s, X86DecodedInsn *decode) -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 10/34] target/i386: tcg: simplify computation of AF after INC/DEC 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (8 preceding siblings ...) 2025-04-23 9:40 ` [PULL 09/34] target/i386: tcg: remove some more uses of temporaries Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 11/34] target/i386: emulate: microoptimize and explain ADD_COUT_VEC/SUB_COUT_VEC Paolo Bonzini ` (24 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel No difference in generated code, but the XOR-based formula is easily understood on its own. This will make more sense once ADD/SUB stop using dst^src1^src2 to compute AF. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/tcg/cc_helper_template.h.inc | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/target/i386/tcg/cc_helper_template.h.inc b/target/i386/tcg/cc_helper_template.h.inc index 9aff16b8801..b821e5bca3b 100644 --- a/target/i386/tcg/cc_helper_template.h.inc +++ b/target/i386/tcg/cc_helper_template.h.inc @@ -175,13 +175,10 @@ static uint32_t glue(compute_all_logic, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) static uint32_t glue(compute_all_inc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) { uint32_t cf, pf, af, zf, sf, of; - DATA_TYPE src2; cf = src1; - src1 = dst - 1; - src2 = 1; pf = compute_pf(dst); - af = (dst ^ src1 ^ src2) & CC_A; + af = (dst ^ (dst - 1)) & CC_A; /* bits 0..3 are all clear */ zf = (dst == 0) * CC_Z; sf = lshift(dst, 8 - DATA_BITS) & CC_S; of = (dst == SIGN_MASK) * CC_O; @@ -191,13 +188,10 @@ static uint32_t glue(compute_all_inc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) static uint32_t glue(compute_all_dec, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) { uint32_t cf, pf, af, zf, sf, of; - DATA_TYPE src2; cf = src1; - src1 = dst + 1; - src2 = 1; pf = compute_pf(dst); - af = (dst ^ src1 ^ src2) & CC_A; + af = (dst ^ (dst + 1)) & CC_A; /* bits 0..3 are all set */ zf = (dst == 0) * CC_Z; sf = lshift(dst, 8 - DATA_BITS) & CC_S; of = (dst == SIGN_MASK - 1) * CC_O; -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 11/34] target/i386: emulate: microoptimize and explain ADD_COUT_VEC/SUB_COUT_VEC 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (9 preceding siblings ...) 2025-04-23 9:40 ` [PULL 10/34] target/i386: tcg: simplify computation of AF after INC/DEC Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 12/34] target/i386: tcg: use cout to commonize add/adc/sub/sbb cases Paolo Bonzini ` (23 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel The logic is the same, but the majority(NOT a, b, c) is brought out to a separate macro and implemented without NOT operations. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86_flags.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/target/i386/hvf/x86_flags.c b/target/i386/hvf/x86_flags.c index fedc70a1b80..60ab4f01a20 100644 --- a/target/i386/hvf/x86_flags.c +++ b/target/i386/hvf/x86_flags.c @@ -45,14 +45,30 @@ #define LF_MASK_CF (0x01 << LF_BIT_CF) #define LF_MASK_PO (0x01 << LF_BIT_PO) +/* majority(NOT a, b, c) = (a ^ b) ? b : c */ +#define MAJ_INV1(a, b, c) ((((a) ^ (b)) & ((b) ^ (c))) ^ (c)) + +/* + * ADD_COUT_VEC(x, y) = majority((x + y) ^ x ^ y, x, y) + * + * If two corresponding bits in x and y are the same, that's the carry + * independent of the value (x+y)^x^y. Hence x^y can be replaced with + * 1 in (x+y)^x^y, resulting in majority(NOT (x+y), x, y) + */ #define ADD_COUT_VEC(op1, op2, result) \ - (((op1) & (op2)) | (((op1) | (op2)) & (~(result)))) + MAJ_INV1(result, op1, op2) +/* + * SUB_COUT_VEC(x, y) = NOT majority(x, NOT y, (x - y) ^ x ^ NOT y) + * = majority(NOT x, y, (x - y) ^ x ^ y) + * + * Note that the carry out is actually a borrow, i.e. it is inverted. + * If two corresponding bits in x and y are different, the value of the + * bit in (x-y)^x^y likewise does not matter. Hence, x^y can be replaced + * with 0 in (x-y)^x^y, resulting in majority(NOT x, y, x-y) + */ #define SUB_COUT_VEC(op1, op2, result) \ - (((~(op1)) & (op2)) | (((~(op1)) ^ (op2)) & (result))) - -#define GET_ADD_OVERFLOW(op1, op2, result, mask) \ - ((((op1) ^ (result)) & ((op2) ^ (result))) & (mask)) + MAJ_INV1(op1, op2, result) /* ******************* */ /* OSZAPC */ -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 12/34] target/i386: tcg: use cout to commonize add/adc/sub/sbb cases 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (10 preceding siblings ...) 2025-04-23 9:40 ` [PULL 11/34] target/i386: emulate: microoptimize and explain ADD_COUT_VEC/SUB_COUT_VEC Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 13/34] target/i386/hvf: introduce x86_emul_ops Paolo Bonzini ` (22 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel Use the carry-out vector as the basis to compute AF, CF and OF. The cost is pretty much the same, because the carry-out is just four boolean operations, and the code is much smaller because add/adc/sub/sbb now share most of it. A similar algorithm to what is used in target/i386/emulate can also be used for APX, in order to build the result of CCMP/CTEST with a new CC_OP_*. CCMP needs to place into the flags from either a subtraction or a constant value; CTEST likewise place into the flags either an AND or a constant value. The new CC_OP for CCMP and CTEST would store for a successful predcate: - in DST and SRC2, the result of the operation; - in SRC, a carry-out vector for CCMP or zero for CTEST; If the default flag value is used, DST/SRC/SRC2 can be filled with constants: - in DST the negated ZF; - in SRC's top 2 bits, a value that results in the desired OF and CF; - in SRC2 a suitable value (any of 0/1/~0/~1) that can be used instead of DST to compute the desired SF and PF. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/cpu.h | 25 ++++++++ target/i386/tcg/cc_helper_template.h.inc | 80 ++++++++---------------- target/i386/hvf/x86_flags.c | 25 -------- 3 files changed, 52 insertions(+), 78 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 76f24446a55..7a8d695bdb1 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2843,4 +2843,29 @@ static inline bool ctl_has_irq(CPUX86State *env) # define TARGET_VSYSCALL_PAGE (UINT64_C(-10) << 20) #endif +/* majority(NOT a, b, c) = (a ^ b) ? b : c */ +#define MAJ_INV1(a, b, c) ((((a) ^ (b)) & ((b) ^ (c))) ^ (c)) + +/* + * ADD_COUT_VEC(x, y) = majority((x + y) ^ x ^ y, x, y) + * + * If two corresponding bits in x and y are the same, that's the carry + * independent of the value (x+y)^x^y. Hence x^y can be replaced with + * 1 in (x+y)^x^y, resulting in majority(NOT (x+y), x, y) + */ +#define ADD_COUT_VEC(op1, op2, result) \ + MAJ_INV1(result, op1, op2) + +/* + * SUB_COUT_VEC(x, y) = NOT majority(x, NOT y, (x - y) ^ x ^ NOT y) + * = majority(NOT x, y, (x - y) ^ x ^ y) + * + * Note that the carry out is actually a borrow, i.e. it is inverted. + * If two corresponding bits in x and y are different, the value of the + * bit in (x-y)^x^y likewise does not matter. Hence, x^y can be replaced + * with 0 in (x-y)^x^y, resulting in majority(NOT x, y, x-y) + */ +#define SUB_COUT_VEC(op1, op2, result) \ + MAJ_INV1(op1, op2, result) + #endif /* I386_CPU_H */ diff --git a/target/i386/tcg/cc_helper_template.h.inc b/target/i386/tcg/cc_helper_template.h.inc index b821e5bca3b..d8fd976ca15 100644 --- a/target/i386/tcg/cc_helper_template.h.inc +++ b/target/i386/tcg/cc_helper_template.h.inc @@ -44,18 +44,32 @@ /* dynamic flags computation */ -static uint32_t glue(compute_all_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) +static uint32_t glue(compute_all_cout, SUFFIX)(DATA_TYPE dst, DATA_TYPE carries) { - uint32_t cf, pf, af, zf, sf, of; - DATA_TYPE src2 = dst - src1; + uint32_t af_cf, pf, zf, sf, of; - cf = dst < src1; + /* PF, ZF, SF computed from result. */ pf = compute_pf(dst); - af = (dst ^ src1 ^ src2) & CC_A; zf = (dst == 0) * CC_Z; sf = lshift(dst, 8 - DATA_BITS) & CC_S; - of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst), 12 - DATA_BITS) & CC_O; - return cf + pf + af + zf + sf + of; + + /* + * AF, CF, OF computed from carry out vector. To compute AF and CF, rotate it + * left by one so cout(DATA_BITS - 1) is in bit 0 and cout(3) in bit 4. + * + * To compute OF, place the highest two carry bits into OF and the bit + * immediately to the right of it; then, adding CC_O / 2 XORs them. + */ + af_cf = ((carries << 1) | (carries >> (DATA_BITS - 1))) & (CC_A | CC_C); + of = (lshift(carries, 12 - DATA_BITS) + CC_O / 2) & CC_O; + return pf + zf + sf + af_cf + of; +} + +static uint32_t glue(compute_all_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) +{ + DATA_TYPE src2 = dst - src1; + DATA_TYPE carries = ADD_COUT_VEC(src1, src2, dst); + return glue(compute_all_cout, SUFFIX)(dst, carries); } static int glue(compute_c_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) @@ -66,25 +80,9 @@ static int glue(compute_c_add, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) static uint32_t glue(compute_all_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1, DATA_TYPE src3) { - uint32_t cf, pf, af, zf, sf, of; - -#ifdef WIDER_TYPE - WIDER_TYPE src13 = (WIDER_TYPE) src1 + (WIDER_TYPE) src3; - DATA_TYPE src2 = dst - src13; - - cf = dst < src13; -#else DATA_TYPE src2 = dst - src1 - src3; - - cf = (src3 ? dst <= src1 : dst < src1); -#endif - - pf = compute_pf(dst); - af = (dst ^ src1 ^ src2) & 0x10; - zf = (dst == 0) << 6; - sf = lshift(dst, 8 - DATA_BITS) & 0x80; - of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst), 12 - DATA_BITS) & CC_O; - return cf + pf + af + zf + sf + of; + DATA_TYPE carries = ADD_COUT_VEC(src1, src2, dst); + return glue(compute_all_cout, SUFFIX)(dst, carries); } static int glue(compute_c_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1, @@ -101,16 +99,9 @@ static int glue(compute_c_adc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1, static uint32_t glue(compute_all_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2) { - uint32_t cf, pf, af, zf, sf, of; DATA_TYPE src1 = dst + src2; - - cf = src1 < src2; - pf = compute_pf(dst); - af = (dst ^ src1 ^ src2) & CC_A; - zf = (dst == 0) * CC_Z; - sf = lshift(dst, 8 - DATA_BITS) & CC_S; - of = lshift((src1 ^ src2) & (src1 ^ dst), 12 - DATA_BITS) & CC_O; - return cf + pf + af + zf + sf + of; + DATA_TYPE carries = SUB_COUT_VEC(src1, src2, dst); + return glue(compute_all_cout, SUFFIX)(dst, carries); } static int glue(compute_c_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2) @@ -123,25 +114,9 @@ static int glue(compute_c_sub, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2) static uint32_t glue(compute_all_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2, DATA_TYPE src3) { - uint32_t cf, pf, af, zf, sf, of; - -#ifdef WIDER_TYPE - WIDER_TYPE src23 = (WIDER_TYPE) src2 + (WIDER_TYPE) src3; - DATA_TYPE src1 = dst + src23; - - cf = src1 < src23; -#else DATA_TYPE src1 = dst + src2 + src3; - - cf = (src3 ? src1 <= src2 : src1 < src2); -#endif - - pf = compute_pf(dst); - af = (dst ^ src1 ^ src2) & 0x10; - zf = (dst == 0) << 6; - sf = lshift(dst, 8 - DATA_BITS) & 0x80; - of = lshift((src1 ^ src2) & (src1 ^ dst), 12 - DATA_BITS) & CC_O; - return cf + pf + af + zf + sf + of; + DATA_TYPE carries = SUB_COUT_VEC(src1, src2, dst); + return glue(compute_all_cout, SUFFIX)(dst, carries); } static int glue(compute_c_sbb, SUFFIX)(DATA_TYPE dst, DATA_TYPE src2, @@ -286,6 +261,5 @@ static int glue(compute_c_blsi, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1) #undef DATA_BITS #undef SIGN_MASK #undef DATA_TYPE -#undef DATA_MASK #undef SUFFIX #undef WIDER_TYPE diff --git a/target/i386/hvf/x86_flags.c b/target/i386/hvf/x86_flags.c index 60ab4f01a20..0c75e0419c3 100644 --- a/target/i386/hvf/x86_flags.c +++ b/target/i386/hvf/x86_flags.c @@ -45,31 +45,6 @@ #define LF_MASK_CF (0x01 << LF_BIT_CF) #define LF_MASK_PO (0x01 << LF_BIT_PO) -/* majority(NOT a, b, c) = (a ^ b) ? b : c */ -#define MAJ_INV1(a, b, c) ((((a) ^ (b)) & ((b) ^ (c))) ^ (c)) - -/* - * ADD_COUT_VEC(x, y) = majority((x + y) ^ x ^ y, x, y) - * - * If two corresponding bits in x and y are the same, that's the carry - * independent of the value (x+y)^x^y. Hence x^y can be replaced with - * 1 in (x+y)^x^y, resulting in majority(NOT (x+y), x, y) - */ -#define ADD_COUT_VEC(op1, op2, result) \ - MAJ_INV1(result, op1, op2) - -/* - * SUB_COUT_VEC(x, y) = NOT majority(x, NOT y, (x - y) ^ x ^ NOT y) - * = majority(NOT x, y, (x - y) ^ x ^ y) - * - * Note that the carry out is actually a borrow, i.e. it is inverted. - * If two corresponding bits in x and y are different, the value of the - * bit in (x-y)^x^y likewise does not matter. Hence, x^y can be replaced - * with 0 in (x-y)^x^y, resulting in majority(NOT x, y, x-y) - */ -#define SUB_COUT_VEC(op1, op2, result) \ - MAJ_INV1(op1, op2, result) - /* ******************* */ /* OSZAPC */ /* ******************* */ -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 13/34] target/i386/hvf: introduce x86_emul_ops 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (11 preceding siblings ...) 2025-04-23 9:40 ` [PULL 12/34] target/i386: tcg: use cout to commonize add/adc/sub/sbb cases Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 14/34] target/i386/hvf: remove HVF specific calls from x86_decode.c Paolo Bonzini ` (21 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> This will be used to remove HVF specific code from the instruction emulator. For now we only introduce two hooks for x86_decode.c. More hooks will be added when the code is refactored. The emulator initialization function now takes in a pointer to the ops structure. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-2-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86_emu.h | 10 +++++++++- target/i386/hvf/hvf.c | 20 +++++++++++++++++++- target/i386/hvf/x86_emu.c | 5 ++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/target/i386/hvf/x86_emu.h b/target/i386/hvf/x86_emu.h index bc0fc72c761..1422d06ea18 100644 --- a/target/i386/hvf/x86_emu.h +++ b/target/i386/hvf/x86_emu.h @@ -23,7 +23,15 @@ #include "x86_decode.h" #include "cpu.h" -void init_emu(void); +struct x86_emul_ops { + void (*read_mem)(CPUState *cpu, void *data, target_ulong addr, int bytes); + void (*read_segment_descriptor)(CPUState *cpu, struct x86_segment_descriptor *desc, + enum X86Seg seg); +}; + +extern const struct x86_emul_ops *emul_ops; + +void init_emu(const struct x86_emul_ops *ops); bool exec_instruction(CPUX86State *env, struct x86_decode *ins); void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_code); diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 9ba0e04ac75..03456ffbc70 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -229,6 +229,24 @@ hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range) return hv_vm_create(HV_VM_DEFAULT); } +static void hvf_read_segment_descriptor(CPUState *s, struct x86_segment_descriptor *desc, + X86Seg seg) +{ + struct vmx_segment vmx_segment; + vmx_read_segment_descriptor(s, &vmx_segment, seg); + vmx_segment_to_x86_descriptor(s, &vmx_segment, desc); +} + +static void hvf_read_mem(CPUState *cpu, void *data, target_ulong gva, int bytes) +{ + vmx_read_mem(cpu, data, gva, bytes); +} + +static const struct x86_emul_ops hvf_x86_emul_ops = { + .read_mem = hvf_read_mem, + .read_segment_descriptor = hvf_read_segment_descriptor, +}; + int hvf_arch_init_vcpu(CPUState *cpu) { X86CPU *x86cpu = X86_CPU(cpu); @@ -237,7 +255,7 @@ int hvf_arch_init_vcpu(CPUState *cpu) int r; uint64_t reqCap; - init_emu(); + init_emu(&hvf_x86_emul_ops); init_decoder(); if (hvf_state->hvf_caps == NULL) { diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index ebba80a36b5..c15b5a7ca85 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -1231,6 +1231,8 @@ static struct cmd_handler { static struct cmd_handler _cmd_handler[X86_DECODE_CMD_LAST]; +const struct x86_emul_ops *emul_ops; + static void init_cmd_handler(void) { int i; @@ -1253,7 +1255,8 @@ bool exec_instruction(CPUX86State *env, struct x86_decode *ins) return true; } -void init_emu(void) +void init_emu(const struct x86_emul_ops *o) { + emul_ops = o; init_cmd_handler(); } -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 14/34] target/i386/hvf: remove HVF specific calls from x86_decode.c 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (12 preceding siblings ...) 2025-04-23 9:40 ` [PULL 13/34] target/i386/hvf: introduce x86_emul_ops Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 15/34] target/i386/hvf: provide and use handle_io in emul_ops Paolo Bonzini ` (20 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> Use the newly defined emul_ops. This allows the module to be reused by other accelerator in the future. No functional change intended. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-3-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86_decode.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c index 5fea2dd3cc0..728e1596381 100644 --- a/target/i386/hvf/x86_decode.c +++ b/target/i386/hvf/x86_decode.c @@ -21,6 +21,7 @@ #include "panic.h" #include "x86_decode.h" #include "vmx.h" +#include "x86_emu.h" #include "x86_mmu.h" #include "x86_descr.h" @@ -74,7 +75,7 @@ static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode, break; } target_ulong va = linear_rip(env_cpu(env), env->eip) + decode->len; - vmx_read_mem(env_cpu(env), &val, va, size); + emul_ops->read_mem(env_cpu(env), &val, va, size); decode->len += size; return val; @@ -1893,16 +1894,6 @@ static void decode_prefix(CPUX86State *env, struct x86_decode *decode) } } -static struct x86_segment_descriptor get_cs_descriptor(CPUState *s) -{ - struct vmx_segment vmx_cs; - x86_segment_descriptor cs; - vmx_read_segment_descriptor(s, &vmx_cs, R_CS); - vmx_segment_to_x86_descriptor(s, &vmx_cs, &cs); - - return cs; -} - void set_addressing_size(CPUX86State *env, struct x86_decode *decode) { decode->addressing_size = -1; @@ -1914,7 +1905,8 @@ void set_addressing_size(CPUX86State *env, struct x86_decode *decode) } } else if (!x86_is_long_mode(env_cpu(env))) { /* protected */ - x86_segment_descriptor cs = get_cs_descriptor(env_cpu(env)); + x86_segment_descriptor cs; + emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS); /* check db */ if (cs.db) { if (decode->addr_size_override) { @@ -1950,7 +1942,8 @@ void set_operand_size(CPUX86State *env, struct x86_decode *decode) } } else if (!x86_is_long_mode(env_cpu(env))) { /* protected */ - x86_segment_descriptor cs = get_cs_descriptor(env_cpu(env)); + x86_segment_descriptor cs; + emul_ops->read_segment_descriptor(env_cpu(env), &cs, R_CS); /* check db */ if (cs.db) { if (decode->op_size_override) { -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 15/34] target/i386/hvf: provide and use handle_io in emul_ops 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (13 preceding siblings ...) 2025-04-23 9:40 ` [PULL 14/34] target/i386/hvf: remove HVF specific calls from x86_decode.c Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 16/34] target/i386: rename hvf_mmio_buf to emu_mmio_buf Paolo Bonzini ` (19 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> This drops the calls to hvf_handle_io from x86_emu.c. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-4-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86_emu.h | 2 ++ target/i386/hvf/hvf.c | 1 + target/i386/hvf/x86_emu.c | 29 +++++++++++++++-------------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/target/i386/hvf/x86_emu.h b/target/i386/hvf/x86_emu.h index 1422d06ea18..40cc786694e 100644 --- a/target/i386/hvf/x86_emu.h +++ b/target/i386/hvf/x86_emu.h @@ -27,6 +27,8 @@ struct x86_emul_ops { void (*read_mem)(CPUState *cpu, void *data, target_ulong addr, int bytes); void (*read_segment_descriptor)(CPUState *cpu, struct x86_segment_descriptor *desc, enum X86Seg seg); + void (*handle_io)(CPUState *cpu, uint16_t port, void *data, int direction, + int size, int count); }; extern const struct x86_emul_ops *emul_ops; diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 03456ffbc70..7da03f9c081 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -245,6 +245,7 @@ static void hvf_read_mem(CPUState *cpu, void *data, target_ulong gva, int bytes) static const struct x86_emul_ops hvf_x86_emul_ops = { .read_mem = hvf_read_mem, .read_segment_descriptor = hvf_read_segment_descriptor, + .handle_io = hvf_handle_io, }; int hvf_arch_init_vcpu(CPUState *cpu) diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index c15b5a7ca85..7b01ccde5d3 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -396,18 +396,18 @@ static void exec_out(CPUX86State *env, struct x86_decode *decode) { switch (decode->opcode[0]) { case 0xe6: - hvf_handle_io(env_cpu(env), decode->op[0].val, &AL(env), 1, 1, 1); + emul_ops->handle_io(env_cpu(env), decode->op[0].val, &AL(env), 1, 1, 1); break; case 0xe7: - hvf_handle_io(env_cpu(env), decode->op[0].val, &RAX(env), 1, - decode->operand_size, 1); + emul_ops->handle_io(env_cpu(env), decode->op[0].val, &RAX(env), 1, + decode->operand_size, 1); break; case 0xee: - hvf_handle_io(env_cpu(env), DX(env), &AL(env), 1, 1, 1); + emul_ops->handle_io(env_cpu(env), DX(env), &AL(env), 1, 1, 1); break; case 0xef: - hvf_handle_io(env_cpu(env), DX(env), &RAX(env), 1, - decode->operand_size, 1); + emul_ops->handle_io(env_cpu(env), DX(env), &RAX(env), 1, + decode->operand_size, 1); break; default: VM_PANIC("Bad out opcode\n"); @@ -421,10 +421,10 @@ static void exec_in(CPUX86State *env, struct x86_decode *decode) target_ulong val = 0; switch (decode->opcode[0]) { case 0xe4: - hvf_handle_io(env_cpu(env), decode->op[0].val, &AL(env), 0, 1, 1); + emul_ops->handle_io(env_cpu(env), decode->op[0].val, &AL(env), 0, 1, 1); break; case 0xe5: - hvf_handle_io(env_cpu(env), decode->op[0].val, &val, 0, + emul_ops->handle_io(env_cpu(env), decode->op[0].val, &val, 0, decode->operand_size, 1); if (decode->operand_size == 2) { AX(env) = val; @@ -433,10 +433,11 @@ static void exec_in(CPUX86State *env, struct x86_decode *decode) } break; case 0xec: - hvf_handle_io(env_cpu(env), DX(env), &AL(env), 0, 1, 1); + emul_ops->handle_io(env_cpu(env), DX(env), &AL(env), 0, 1, 1); break; case 0xed: - hvf_handle_io(env_cpu(env), DX(env), &val, 0, decode->operand_size, 1); + emul_ops->handle_io(env_cpu(env), DX(env), &val, 0, + decode->operand_size, 1); if (decode->operand_size == 2) { AX(env) = val; } else { @@ -486,8 +487,8 @@ static void exec_ins_single(CPUX86State *env, struct x86_decode *decode) target_ulong addr = linear_addr_size(env_cpu(env), RDI(env), decode->addressing_size, R_ES); - hvf_handle_io(env_cpu(env), DX(env), env->hvf_mmio_buf, 0, - decode->operand_size, 1); + emul_ops->handle_io(env_cpu(env), DX(env), env->hvf_mmio_buf, 0, + decode->operand_size, 1); vmx_write_mem(env_cpu(env), addr, env->hvf_mmio_buf, decode->operand_size); @@ -511,8 +512,8 @@ static void exec_outs_single(CPUX86State *env, struct x86_decode *decode) vmx_read_mem(env_cpu(env), env->hvf_mmio_buf, addr, decode->operand_size); - hvf_handle_io(env_cpu(env), DX(env), env->hvf_mmio_buf, 1, - decode->operand_size, 1); + emul_ops->handle_io(env_cpu(env), DX(env), env->hvf_mmio_buf, 1, + decode->operand_size, 1); string_increment_reg(env, R_ESI, decode); } -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 16/34] target/i386: rename hvf_mmio_buf to emu_mmio_buf 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (14 preceding siblings ...) 2025-04-23 9:40 ` [PULL 15/34] target/i386/hvf: provide and use handle_io in emul_ops Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 17/34] target/i386/hvf: use emul_ops->read_mem in x86_emu.c Paolo Bonzini ` (18 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> We want to refactor HVF's instruction emulator to a common component. Renaming hvf_mmio_buf removes the association between HVF and the instruction emulator. The definition of the field is still guarded by CONFIG_HVF for now, since it is the only user. No functional change. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-5-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/cpu.h | 2 +- target/i386/hvf/hvf.c | 4 ++-- target/i386/hvf/x86_emu.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 7a8d695bdb1..3c5c39ce3d3 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2109,7 +2109,7 @@ typedef struct CPUArchState { #endif #if defined(CONFIG_HVF) HVFX86LazyFlags hvf_lflags; - void *hvf_mmio_buf; + void *emu_mmio_buf; #endif uint64_t mcg_cap; diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 7da03f9c081..1cecb765952 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -168,7 +168,7 @@ void hvf_arch_vcpu_destroy(CPUState *cpu) X86CPU *x86_cpu = X86_CPU(cpu); CPUX86State *env = &x86_cpu->env; - g_free(env->hvf_mmio_buf); + g_free(env->emu_mmio_buf); } static void init_tsc_freq(CPUX86State *env) @@ -262,7 +262,7 @@ int hvf_arch_init_vcpu(CPUState *cpu) if (hvf_state->hvf_caps == NULL) { hvf_state->hvf_caps = g_new0(struct hvf_vcpu_caps, 1); } - env->hvf_mmio_buf = g_new(char, 4096); + env->emu_mmio_buf = g_new(char, 4096); if (x86cpu->vmware_cpuid_freq) { init_tsc_freq(env); diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index 7b01ccde5d3..e59a73e00d5 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -184,8 +184,8 @@ void write_val_ext(CPUX86State *env, target_ulong ptr, target_ulong val, int siz uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes) { - vmx_read_mem(env_cpu(env), env->hvf_mmio_buf, ptr, bytes); - return env->hvf_mmio_buf; + vmx_read_mem(env_cpu(env), env->emu_mmio_buf, ptr, bytes); + return env->emu_mmio_buf; } @@ -487,9 +487,9 @@ static void exec_ins_single(CPUX86State *env, struct x86_decode *decode) target_ulong addr = linear_addr_size(env_cpu(env), RDI(env), decode->addressing_size, R_ES); - emul_ops->handle_io(env_cpu(env), DX(env), env->hvf_mmio_buf, 0, + emul_ops->handle_io(env_cpu(env), DX(env), env->emu_mmio_buf, 0, decode->operand_size, 1); - vmx_write_mem(env_cpu(env), addr, env->hvf_mmio_buf, + vmx_write_mem(env_cpu(env), addr, env->emu_mmio_buf, decode->operand_size); string_increment_reg(env, R_EDI, decode); @@ -510,9 +510,9 @@ static void exec_outs_single(CPUX86State *env, struct x86_decode *decode) { target_ulong addr = decode_linear_addr(env, decode, RSI(env), R_DS); - vmx_read_mem(env_cpu(env), env->hvf_mmio_buf, addr, + vmx_read_mem(env_cpu(env), env->emu_mmio_buf, addr, decode->operand_size); - emul_ops->handle_io(env_cpu(env), DX(env), env->hvf_mmio_buf, 1, + emul_ops->handle_io(env_cpu(env), DX(env), env->emu_mmio_buf, 1, decode->operand_size, 1); string_increment_reg(env, R_ESI, decode); -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 17/34] target/i386/hvf: use emul_ops->read_mem in x86_emu.c 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (15 preceding siblings ...) 2025-04-23 9:40 ` [PULL 16/34] target/i386: rename hvf_mmio_buf to emu_mmio_buf Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 18/34] target/i386/hvf: provide and use write_mem in emul_ops Paolo Bonzini ` (17 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> No functional change. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-6-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86_emu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index e59a73e00d5..7b816b5a1da 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -184,7 +184,7 @@ void write_val_ext(CPUX86State *env, target_ulong ptr, target_ulong val, int siz uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes) { - vmx_read_mem(env_cpu(env), env->emu_mmio_buf, ptr, bytes); + emul_ops->read_mem(env_cpu(env), env->emu_mmio_buf, ptr, bytes); return env->emu_mmio_buf; } @@ -510,8 +510,8 @@ static void exec_outs_single(CPUX86State *env, struct x86_decode *decode) { target_ulong addr = decode_linear_addr(env, decode, RSI(env), R_DS); - vmx_read_mem(env_cpu(env), env->emu_mmio_buf, addr, - decode->operand_size); + emul_ops->read_mem(env_cpu(env), env->emu_mmio_buf, addr, + decode->operand_size); emul_ops->handle_io(env_cpu(env), DX(env), env->emu_mmio_buf, 1, decode->operand_size, 1); @@ -620,7 +620,7 @@ static void exec_scas_single(CPUX86State *env, struct x86_decode *decode) addr = linear_addr_size(env_cpu(env), RDI(env), decode->addressing_size, R_ES); decode->op[1].type = X86_VAR_IMMEDIATE; - vmx_read_mem(env_cpu(env), &decode->op[1].val, addr, decode->operand_size); + emul_ops->read_mem(env_cpu(env), &decode->op[1].val, addr, decode->operand_size); EXEC_2OP_FLAGS_CMD(env, decode, -, SET_FLAGS_OSZAPC_SUB, false); string_increment_reg(env, R_EDI, decode); @@ -645,7 +645,7 @@ static void exec_lods_single(CPUX86State *env, struct x86_decode *decode) target_ulong val = 0; addr = decode_linear_addr(env, decode, RSI(env), R_DS); - vmx_read_mem(env_cpu(env), &val, addr, decode->operand_size); + emul_ops->read_mem(env_cpu(env), &val, addr, decode->operand_size); write_reg(env, R_EAX, val, decode->operand_size); string_increment_reg(env, R_ESI, decode); -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 18/34] target/i386/hvf: provide and use write_mem in emul_ops 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (16 preceding siblings ...) 2025-04-23 9:40 ` [PULL 17/34] target/i386/hvf: use emul_ops->read_mem in x86_emu.c Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 19/34] target/i386/hvf: provide and use simulate_{wrmsr, rdmsr} " Paolo Bonzini ` (16 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-7-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86_emu.h | 1 + target/i386/hvf/hvf.c | 6 ++++++ target/i386/hvf/x86_emu.c | 8 ++++---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/target/i386/hvf/x86_emu.h b/target/i386/hvf/x86_emu.h index 40cc786694e..107c1f1ac86 100644 --- a/target/i386/hvf/x86_emu.h +++ b/target/i386/hvf/x86_emu.h @@ -25,6 +25,7 @@ struct x86_emul_ops { void (*read_mem)(CPUState *cpu, void *data, target_ulong addr, int bytes); + void (*write_mem)(CPUState *cpu, void *data, target_ulong addr, int bytes); void (*read_segment_descriptor)(CPUState *cpu, struct x86_segment_descriptor *desc, enum X86Seg seg); void (*handle_io)(CPUState *cpu, uint16_t port, void *data, int direction, diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 1cecb765952..e4f48a79fb7 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -242,8 +242,14 @@ static void hvf_read_mem(CPUState *cpu, void *data, target_ulong gva, int bytes) vmx_read_mem(cpu, data, gva, bytes); } +static void hvf_write_mem(CPUState *cpu, void *data, target_ulong gva, int bytes) +{ + vmx_write_mem(cpu, gva, data, bytes); +} + static const struct x86_emul_ops hvf_x86_emul_ops = { .read_mem = hvf_read_mem, + .write_mem = hvf_write_mem, .read_segment_descriptor = hvf_read_segment_descriptor, .handle_io = hvf_handle_io, }; diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index 7b816b5a1da..3ff41c35d89 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -179,7 +179,7 @@ void write_val_ext(CPUX86State *env, target_ulong ptr, target_ulong val, int siz write_val_to_reg(ptr, val, size); return; } - vmx_write_mem(env_cpu(env), ptr, &val, size); + emul_ops->write_mem(env_cpu(env), &val, ptr, size); } uint8_t *read_mmio(CPUX86State *env, target_ulong ptr, int bytes) @@ -489,8 +489,8 @@ static void exec_ins_single(CPUX86State *env, struct x86_decode *decode) emul_ops->handle_io(env_cpu(env), DX(env), env->emu_mmio_buf, 0, decode->operand_size, 1); - vmx_write_mem(env_cpu(env), addr, env->emu_mmio_buf, - decode->operand_size); + emul_ops->write_mem(env_cpu(env), env->emu_mmio_buf, addr, + decode->operand_size); string_increment_reg(env, R_EDI, decode); } @@ -596,7 +596,7 @@ static void exec_stos_single(CPUX86State *env, struct x86_decode *decode) addr = linear_addr_size(env_cpu(env), RDI(env), decode->addressing_size, R_ES); val = read_reg(env, R_EAX, decode->operand_size); - vmx_write_mem(env_cpu(env), addr, &val, decode->operand_size); + emul_ops->write_mem(env_cpu(env), &val, addr, decode->operand_size); string_increment_reg(env, R_EDI, decode); } -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 19/34] target/i386/hvf: provide and use simulate_{wrmsr, rdmsr} in emul_ops 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (17 preceding siblings ...) 2025-04-23 9:40 ` [PULL 18/34] target/i386/hvf: provide and use write_mem in emul_ops Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 20/34] target/i386: rename lazy flags field and its type Paolo Bonzini ` (15 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> Change the first argument's type to be CPUState to match other hooks. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-8-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/hvf-i386.h | 4 ++-- target/i386/hvf/x86_emu.h | 2 ++ target/i386/hvf/hvf.c | 18 ++++++++++-------- target/i386/hvf/x86_emu.c | 4 ++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h index 044ad236ae8..8c42ae6b013 100644 --- a/target/i386/hvf/hvf-i386.h +++ b/target/i386/hvf/hvf-i386.h @@ -19,8 +19,8 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, int reg); void hvf_handle_io(CPUState *, uint16_t, void *, int, int, int); -void hvf_simulate_rdmsr(CPUX86State *env); -void hvf_simulate_wrmsr(CPUX86State *env); +void hvf_simulate_rdmsr(CPUState *cpu); +void hvf_simulate_wrmsr(CPUState *cpu); /* Host specific functions */ int hvf_inject_interrupt(CPUArchState *env, int vector); diff --git a/target/i386/hvf/x86_emu.h b/target/i386/hvf/x86_emu.h index 107c1f1ac86..555b567e2c7 100644 --- a/target/i386/hvf/x86_emu.h +++ b/target/i386/hvf/x86_emu.h @@ -30,6 +30,8 @@ struct x86_emul_ops { enum X86Seg seg); void (*handle_io)(CPUState *cpu, uint16_t port, void *data, int direction, int size, int count); + void (*simulate_rdmsr)(CPUState *cs); + void (*simulate_wrmsr)(CPUState *cs); }; extern const struct x86_emul_ops *emul_ops; diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index e4f48a79fb7..8c31d2e0cf7 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -252,6 +252,8 @@ static const struct x86_emul_ops hvf_x86_emul_ops = { .write_mem = hvf_write_mem, .read_segment_descriptor = hvf_read_segment_descriptor, .handle_io = hvf_handle_io, + .simulate_rdmsr = hvf_simulate_rdmsr, + .simulate_wrmsr = hvf_simulate_wrmsr, }; int hvf_arch_init_vcpu(CPUState *cpu) @@ -506,10 +508,10 @@ void hvf_store_regs(CPUState *cs) macvm_set_rip(cs, env->eip); } -void hvf_simulate_rdmsr(CPUX86State *env) +void hvf_simulate_rdmsr(CPUState *cs) { - X86CPU *cpu = env_archcpu(env); - CPUState *cs = env_cpu(env); + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; uint32_t msr = ECX(env); uint64_t val = 0; @@ -611,10 +613,10 @@ void hvf_simulate_rdmsr(CPUX86State *env) RDX(env) = (uint32_t)(val >> 32); } -void hvf_simulate_wrmsr(CPUX86State *env) +void hvf_simulate_wrmsr(CPUState *cs) { - X86CPU *cpu = env_archcpu(env); - CPUState *cs = env_cpu(env); + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; uint32_t msr = ECX(env); uint64_t data = ((uint64_t)EDX(env) << 32) | EAX(env); @@ -900,9 +902,9 @@ int hvf_vcpu_exec(CPUState *cpu) { hvf_load_regs(cpu); if (exit_reason == EXIT_REASON_RDMSR) { - hvf_simulate_rdmsr(env); + hvf_simulate_rdmsr(cpu); } else { - hvf_simulate_wrmsr(env); + hvf_simulate_wrmsr(cpu); } env->eip += ins_len; hvf_store_regs(cpu); diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index 3ff41c35d89..aec7a8a3fa8 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -672,13 +672,13 @@ void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_c static void exec_rdmsr(CPUX86State *env, struct x86_decode *decode) { - hvf_simulate_rdmsr(env); + emul_ops->simulate_rdmsr(env_cpu(env)); env->eip += decode->len; } static void exec_wrmsr(CPUX86State *env, struct x86_decode *decode) { - hvf_simulate_wrmsr(env); + emul_ops->simulate_wrmsr(env_cpu(env)); env->eip += decode->len; } -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 20/34] target/i386: rename lazy flags field and its type 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (18 preceding siblings ...) 2025-04-23 9:40 ` [PULL 19/34] target/i386/hvf: provide and use simulate_{wrmsr, rdmsr} " Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 21/34] target/i386/hvf: drop unused headers Paolo Bonzini ` (14 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> The same structure and code can be used by other accelerators. Drop the hvf prefix in the type and field name. No functional change. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-9-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/cpu.h | 6 ++-- target/i386/hvf/x86_flags.c | 56 ++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 3c5c39ce3d3..119efc6c605 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1811,10 +1811,10 @@ typedef struct CPUCaches { CPUCacheInfo *l3_cache; } CPUCaches; -typedef struct HVFX86LazyFlags { +typedef struct X86LazyFlags { target_ulong result; target_ulong auxbits; -} HVFX86LazyFlags; +} X86LazyFlags; typedef struct CPUArchState { /* standard registers */ @@ -2108,7 +2108,7 @@ typedef struct CPUArchState { QemuMutex xen_timers_lock; #endif #if defined(CONFIG_HVF) - HVFX86LazyFlags hvf_lflags; + X86LazyFlags lflags; void *emu_mmio_buf; #endif diff --git a/target/i386/hvf/x86_flags.c b/target/i386/hvf/x86_flags.c index 0c75e0419c3..84e27364a03 100644 --- a/target/i386/hvf/x86_flags.c +++ b/target/i386/hvf/x86_flags.c @@ -53,7 +53,7 @@ #define SET_FLAGS_OSZAPC_SIZE(size, lf_carries, lf_result) { \ target_ulong temp = ((lf_carries) & (LF_MASK_AF)) | \ (((lf_carries) >> (size - 2)) << LF_BIT_PO); \ - env->hvf_lflags.result = (target_ulong)(int##size##_t)(lf_result); \ + env->lflags.result = (target_ulong)(int##size##_t)(lf_result); \ if ((size) == 32) { \ temp = ((lf_carries) & ~(LF_MASK_PDB | LF_MASK_SD)); \ } else if ((size) == 16) { \ @@ -63,7 +63,7 @@ } else { \ VM_PANIC("unimplemented"); \ } \ - env->hvf_lflags.auxbits = (target_ulong)(uint32_t)temp; \ + env->lflags.auxbits = (target_ulong)(uint32_t)temp; \ } /* carries, result */ @@ -90,10 +90,10 @@ } else { \ VM_PANIC("unimplemented"); \ } \ - env->hvf_lflags.result = (target_ulong)(int##size##_t)(lf_result); \ - target_ulong delta_c = (env->hvf_lflags.auxbits ^ temp) & LF_MASK_CF; \ + env->lflags.result = (target_ulong)(int##size##_t)(lf_result); \ + target_ulong delta_c = (env->lflags.auxbits ^ temp) & LF_MASK_CF; \ delta_c ^= (delta_c >> 1); \ - env->hvf_lflags.auxbits = (target_ulong)(uint32_t)(temp ^ delta_c); \ + env->lflags.auxbits = (target_ulong)(uint32_t)(temp ^ delta_c); \ } /* carries, result */ @@ -107,8 +107,8 @@ void SET_FLAGS_OxxxxC(CPUX86State *env, uint32_t new_of, uint32_t new_cf) { uint32_t temp_po = new_of ^ new_cf; - env->hvf_lflags.auxbits &= ~(LF_MASK_PO | LF_MASK_CF); - env->hvf_lflags.auxbits |= (temp_po << LF_BIT_PO) | (new_cf << LF_BIT_CF); + env->lflags.auxbits &= ~(LF_MASK_PO | LF_MASK_CF); + env->lflags.auxbits |= (temp_po << LF_BIT_PO) | (new_cf << LF_BIT_CF); } void SET_FLAGS_OSZAPC_SUB32(CPUX86State *env, uint32_t v1, uint32_t v2, @@ -204,27 +204,27 @@ void SET_FLAGS_OSZAPC_LOGIC8(CPUX86State *env, uint8_t v1, uint8_t v2, bool get_PF(CPUX86State *env) { - uint32_t temp = (255 & env->hvf_lflags.result); - temp = temp ^ (255 & (env->hvf_lflags.auxbits >> LF_BIT_PDB)); + uint32_t temp = (255 & env->lflags.result); + temp = temp ^ (255 & (env->lflags.auxbits >> LF_BIT_PDB)); temp = (temp ^ (temp >> 4)) & 0x0F; return (0x9669U >> temp) & 1; } void set_PF(CPUX86State *env, bool val) { - uint32_t temp = (255 & env->hvf_lflags.result) ^ (!val); - env->hvf_lflags.auxbits &= ~(LF_MASK_PDB); - env->hvf_lflags.auxbits |= (temp << LF_BIT_PDB); + uint32_t temp = (255 & env->lflags.result) ^ (!val); + env->lflags.auxbits &= ~(LF_MASK_PDB); + env->lflags.auxbits |= (temp << LF_BIT_PDB); } bool get_OF(CPUX86State *env) { - return ((env->hvf_lflags.auxbits + (1U << LF_BIT_PO)) >> LF_BIT_CF) & 1; + return ((env->lflags.auxbits + (1U << LF_BIT_PO)) >> LF_BIT_CF) & 1; } bool get_CF(CPUX86State *env) { - return (env->hvf_lflags.auxbits >> LF_BIT_CF) & 1; + return (env->lflags.auxbits >> LF_BIT_CF) & 1; } void set_OF(CPUX86State *env, bool val) @@ -241,45 +241,45 @@ void set_CF(CPUX86State *env, bool val) bool get_AF(CPUX86State *env) { - return (env->hvf_lflags.auxbits >> LF_BIT_AF) & 1; + return (env->lflags.auxbits >> LF_BIT_AF) & 1; } void set_AF(CPUX86State *env, bool val) { - env->hvf_lflags.auxbits &= ~(LF_MASK_AF); - env->hvf_lflags.auxbits |= val << LF_BIT_AF; + env->lflags.auxbits &= ~(LF_MASK_AF); + env->lflags.auxbits |= val << LF_BIT_AF; } bool get_ZF(CPUX86State *env) { - return !env->hvf_lflags.result; + return !env->lflags.result; } void set_ZF(CPUX86State *env, bool val) { if (val) { - env->hvf_lflags.auxbits ^= - (((env->hvf_lflags.result >> LF_SIGN_BIT) & 1) << LF_BIT_SD); + env->lflags.auxbits ^= + (((env->lflags.result >> LF_SIGN_BIT) & 1) << LF_BIT_SD); /* merge the parity bits into the Parity Delta Byte */ - uint32_t temp_pdb = (255 & env->hvf_lflags.result); - env->hvf_lflags.auxbits ^= (temp_pdb << LF_BIT_PDB); + uint32_t temp_pdb = (255 & env->lflags.result); + env->lflags.auxbits ^= (temp_pdb << LF_BIT_PDB); /* now zero the .result value */ - env->hvf_lflags.result = 0; + env->lflags.result = 0; } else { - env->hvf_lflags.result |= (1 << 8); + env->lflags.result |= (1 << 8); } } bool get_SF(CPUX86State *env) { - return ((env->hvf_lflags.result >> LF_SIGN_BIT) ^ - (env->hvf_lflags.auxbits >> LF_BIT_SD)) & 1; + return ((env->lflags.result >> LF_SIGN_BIT) ^ + (env->lflags.auxbits >> LF_BIT_SD)) & 1; } void set_SF(CPUX86State *env, bool val) { bool temp_sf = get_SF(env); - env->hvf_lflags.auxbits ^= (temp_sf ^ val) << LF_BIT_SD; + env->lflags.auxbits ^= (temp_sf ^ val) << LF_BIT_SD; } void lflags_to_rflags(CPUX86State *env) @@ -295,7 +295,7 @@ void lflags_to_rflags(CPUX86State *env) void rflags_to_lflags(CPUX86State *env) { - env->hvf_lflags.auxbits = env->hvf_lflags.result = 0; + env->lflags.auxbits = env->lflags.result = 0; set_OF(env, env->eflags & CC_O); set_SF(env, env->eflags & CC_S); set_ZF(env, env->eflags & CC_Z); -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 21/34] target/i386/hvf: drop unused headers 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (19 preceding siblings ...) 2025-04-23 9:40 ` [PULL 20/34] target/i386: rename lazy flags field and its type Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 22/34] target/i386/hvf: rename some include guards Paolo Bonzini ` (13 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-10-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86_decode.c | 3 --- target/i386/hvf/x86_emu.c | 4 ---- 2 files changed, 7 deletions(-) diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c index 728e1596381..ddd7b60bcfe 100644 --- a/target/i386/hvf/x86_decode.c +++ b/target/i386/hvf/x86_decode.c @@ -20,10 +20,7 @@ #include "panic.h" #include "x86_decode.h" -#include "vmx.h" #include "x86_emu.h" -#include "x86_mmu.h" -#include "x86_descr.h" #define OPCODE_ESCAPE 0xf diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index aec7a8a3fa8..26a4876aac0 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -40,11 +40,7 @@ #include "x86_decode.h" #include "x86.h" #include "x86_emu.h" -#include "x86_mmu.h" #include "x86_flags.h" -#include "vmcs.h" -#include "vmx.h" -#include "hvf-i386.h" #define EXEC_2OP_FLAGS_CMD(env, decode, cmd, FLAGS_FUNC, save_res) \ { \ -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 22/34] target/i386/hvf: rename some include guards 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (20 preceding siblings ...) 2025-04-23 9:40 ` [PULL 21/34] target/i386/hvf: drop unused headers Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 23/34] target/i386: add a directory for x86 instruction emulator Paolo Bonzini ` (12 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> These headers will be moved out to its own component. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-11-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/hvf/x86.h | 4 ++-- target/i386/hvf/x86_decode.h | 4 ++-- target/i386/hvf/x86_flags.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/target/i386/hvf/x86.h b/target/i386/hvf/x86.h index 063cd0b83ec..73edccfba00 100644 --- a/target/i386/hvf/x86.h +++ b/target/i386/hvf/x86.h @@ -16,8 +16,8 @@ * License along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef HVF_X86_H -#define HVF_X86_H +#ifndef X86_EMU_DEFS_H +#define X86_EMU_DEFS_H typedef struct x86_register { union { diff --git a/target/i386/hvf/x86_decode.h b/target/i386/hvf/x86_decode.h index a2d7a2a27b6..930d965164a 100644 --- a/target/i386/hvf/x86_decode.h +++ b/target/i386/hvf/x86_decode.h @@ -15,8 +15,8 @@ * License along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef HVF_X86_DECODE_H -#define HVF_X86_DECODE_H +#ifndef X86_EMU_DECODE_H +#define X86_EMU_DECODE_H #include "cpu.h" #include "x86.h" diff --git a/target/i386/hvf/x86_flags.h b/target/i386/hvf/x86_flags.h index 75c2a7feab5..6c175007b57 100644 --- a/target/i386/hvf/x86_flags.h +++ b/target/i386/hvf/x86_flags.h @@ -21,8 +21,8 @@ * x86 eflags functions */ -#ifndef X86_FLAGS_H -#define X86_FLAGS_H +#ifndef X86_EMU_FLAGS_H +#define X86_EMU_FLAGS_H #include "cpu.h" void lflags_to_rflags(CPUX86State *env); @@ -78,4 +78,4 @@ void SET_FLAGS_OSZAPC_LOGIC16(CPUX86State *env, uint16_t v1, uint16_t v2, void SET_FLAGS_OSZAPC_LOGIC8(CPUX86State *env, uint8_t v1, uint8_t v2, uint8_t diff); -#endif /* X86_FLAGS_H */ +#endif /* X86_EMU_FLAGS_H */ -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 23/34] target/i386: add a directory for x86 instruction emulator 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (21 preceding siblings ...) 2025-04-23 9:40 ` [PULL 22/34] target/i386/hvf: rename some include guards Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 24/34] target/i386/emulate: add a panic.h Paolo Bonzini ` (11 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-12-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/emulate/meson.build | 0 target/i386/meson.build | 1 + 2 files changed, 1 insertion(+) create mode 100644 target/i386/emulate/meson.build diff --git a/target/i386/emulate/meson.build b/target/i386/emulate/meson.build new file mode 100644 index 00000000000..e69de29bb2d diff --git a/target/i386/meson.build b/target/i386/meson.build index 2e9c472f49d..c1aacea6135 100644 --- a/target/i386/meson.build +++ b/target/i386/meson.build @@ -31,6 +31,7 @@ subdir('whpx') subdir('nvmm') subdir('hvf') subdir('tcg') +subdir('emulate') target_arch += {'i386': i386_ss} target_system_arch += {'i386': i386_system_ss} -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 24/34] target/i386/emulate: add a panic.h 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (22 preceding siblings ...) 2025-04-23 9:40 ` [PULL 23/34] target/i386: add a directory for x86 instruction emulator Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 25/34] target/i386: move x86 instruction emulator out of hvf Paolo Bonzini ` (10 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> The macros will be used by the instruction emulator. The code is the same as the one under hvf. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-13-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/emulate/panic.h | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 target/i386/emulate/panic.h diff --git a/target/i386/emulate/panic.h b/target/i386/emulate/panic.h new file mode 100644 index 00000000000..71c24874ba0 --- /dev/null +++ b/target/i386/emulate/panic.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 Veertu Inc, + * Copyright (C) 2017 Google Inc, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef X86_EMU_PANIC_H +#define X86_EMU_PANIC_H + +#define VM_PANIC(x) {\ + printf("%s\n", x); \ + abort(); \ +} + +#define VM_PANIC_ON(x) {\ + if (x) { \ + printf("%s\n", #x); \ + abort(); \ + } \ +} + +#define VM_PANIC_EX(...) {\ + printf(__VA_ARGS__); \ + abort(); \ +} + +#define VM_PANIC_ON_EX(x, ...) {\ + if (x) { \ + printf(__VA_ARGS__); \ + abort(); \ + } \ +} + +#endif -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 25/34] target/i386: move x86 instruction emulator out of hvf 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (23 preceding siblings ...) 2025-04-23 9:40 ` [PULL 24/34] target/i386/emulate: add a panic.h Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 26/34] MAINTAINERS: add an entry for the x86 instruction emulator Paolo Bonzini ` (9 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> Move x86_decode, x86_emu, x86_flags and some headers to the new location. Fix up all the inclusion sites in hvf. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-14-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/{hvf => emulate}/x86.h | 0 target/i386/{hvf => emulate}/x86_decode.h | 0 target/i386/{hvf => emulate}/x86_emu.h | 0 target/i386/{hvf => emulate}/x86_flags.h | 0 target/i386/hvf/vmx.h | 2 +- target/i386/hvf/x86_descr.h | 2 +- target/i386/{hvf => emulate}/x86_decode.c | 0 target/i386/{hvf => emulate}/x86_emu.c | 0 target/i386/{hvf => emulate}/x86_flags.c | 0 target/i386/hvf/hvf.c | 8 ++++---- target/i386/hvf/x86.c | 4 ++-- target/i386/hvf/x86_cpuid.c | 2 +- target/i386/hvf/x86_mmu.c | 2 +- target/i386/hvf/x86_task.c | 6 +++--- target/i386/hvf/x86hvf.c | 2 +- target/i386/emulate/meson.build | 5 +++++ target/i386/hvf/meson.build | 3 --- 17 files changed, 19 insertions(+), 17 deletions(-) rename target/i386/{hvf => emulate}/x86.h (100%) rename target/i386/{hvf => emulate}/x86_decode.h (100%) rename target/i386/{hvf => emulate}/x86_emu.h (100%) rename target/i386/{hvf => emulate}/x86_flags.h (100%) rename target/i386/{hvf => emulate}/x86_decode.c (100%) rename target/i386/{hvf => emulate}/x86_emu.c (100%) rename target/i386/{hvf => emulate}/x86_flags.c (100%) diff --git a/target/i386/hvf/x86.h b/target/i386/emulate/x86.h similarity index 100% rename from target/i386/hvf/x86.h rename to target/i386/emulate/x86.h diff --git a/target/i386/hvf/x86_decode.h b/target/i386/emulate/x86_decode.h similarity index 100% rename from target/i386/hvf/x86_decode.h rename to target/i386/emulate/x86_decode.h diff --git a/target/i386/hvf/x86_emu.h b/target/i386/emulate/x86_emu.h similarity index 100% rename from target/i386/hvf/x86_emu.h rename to target/i386/emulate/x86_emu.h diff --git a/target/i386/hvf/x86_flags.h b/target/i386/emulate/x86_flags.h similarity index 100% rename from target/i386/hvf/x86_flags.h rename to target/i386/emulate/x86_flags.h diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h index 80ce26279bf..3c56afc9d3a 100644 --- a/target/i386/hvf/vmx.h +++ b/target/i386/hvf/vmx.h @@ -29,7 +29,7 @@ #include <Hypervisor/hv_vmx.h> #include "vmcs.h" #include "cpu.h" -#include "x86.h" +#include "emulate/x86.h" #include "system/hvf.h" #include "system/hvf_int.h" diff --git a/target/i386/hvf/x86_descr.h b/target/i386/hvf/x86_descr.h index ce5de983497..24af4946cd4 100644 --- a/target/i386/hvf/x86_descr.h +++ b/target/i386/hvf/x86_descr.h @@ -19,7 +19,7 @@ #ifndef HVF_X86_DESCR_H #define HVF_X86_DESCR_H -#include "x86.h" +#include "emulate/x86.h" typedef struct vmx_segment { uint16_t sel; diff --git a/target/i386/hvf/x86_decode.c b/target/i386/emulate/x86_decode.c similarity index 100% rename from target/i386/hvf/x86_decode.c rename to target/i386/emulate/x86_decode.c diff --git a/target/i386/hvf/x86_emu.c b/target/i386/emulate/x86_emu.c similarity index 100% rename from target/i386/hvf/x86_emu.c rename to target/i386/emulate/x86_emu.c diff --git a/target/i386/hvf/x86_flags.c b/target/i386/emulate/x86_flags.c similarity index 100% rename from target/i386/hvf/x86_flags.c rename to target/i386/emulate/x86_flags.c diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 8c31d2e0cf7..23ebf2550ac 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -59,12 +59,12 @@ #include "hvf-i386.h" #include "vmcs.h" #include "vmx.h" -#include "x86.h" +#include "emulate/x86.h" #include "x86_descr.h" -#include "x86_flags.h" +#include "emulate/x86_flags.h" #include "x86_mmu.h" -#include "x86_decode.h" -#include "x86_emu.h" +#include "emulate/x86_decode.h" +#include "emulate/x86_emu.h" #include "x86_task.h" #include "x86hvf.h" diff --git a/target/i386/hvf/x86.c b/target/i386/hvf/x86.c index a0ede138865..5c75ec9a007 100644 --- a/target/i386/hvf/x86.c +++ b/target/i386/hvf/x86.c @@ -19,8 +19,8 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "x86_decode.h" -#include "x86_emu.h" +#include "emulate/x86_decode.h" +#include "emulate/x86_emu.h" #include "vmcs.h" #include "vmx.h" #include "x86_mmu.h" diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c index ae836f65cc9..fa131b18c6d 100644 --- a/target/i386/hvf/x86_cpuid.c +++ b/target/i386/hvf/x86_cpuid.c @@ -24,7 +24,7 @@ #include "qemu/cpuid.h" #include "host/cpuinfo.h" #include "cpu.h" -#include "x86.h" +#include "emulate/x86.h" #include "vmx.h" #include "system/hvf.h" #include "hvf-i386.h" diff --git a/target/i386/hvf/x86_mmu.c b/target/i386/hvf/x86_mmu.c index 579d0c3a4cc..afc5c17d5d5 100644 --- a/target/i386/hvf/x86_mmu.c +++ b/target/i386/hvf/x86_mmu.c @@ -19,7 +19,7 @@ #include "qemu/osdep.h" #include "panic.h" #include "cpu.h" -#include "x86.h" +#include "emulate/x86.h" #include "x86_mmu.h" #include "vmcs.h" #include "vmx.h" diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c index 161217991fc..bdf8b51ae67 100644 --- a/target/i386/hvf/x86_task.c +++ b/target/i386/hvf/x86_task.c @@ -14,11 +14,11 @@ #include "hvf-i386.h" #include "vmcs.h" #include "vmx.h" -#include "x86.h" +#include "emulate/x86.h" #include "x86_descr.h" #include "x86_mmu.h" -#include "x86_decode.h" -#include "x86_emu.h" +#include "emulate/x86_decode.h" +#include "emulate/x86_emu.h" #include "x86_task.h" #include "x86hvf.h" diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c index 531a340b37c..2057314892a 100644 --- a/target/i386/hvf/x86hvf.c +++ b/target/i386/hvf/x86hvf.c @@ -24,7 +24,7 @@ #include "vmcs.h" #include "cpu.h" #include "x86_descr.h" -#include "x86_decode.h" +#include "emulate/x86_decode.h" #include "system/hw_accel.h" #include "hw/i386/apic_internal.h" diff --git a/target/i386/emulate/meson.build b/target/i386/emulate/meson.build index e69de29bb2d..4edd4f462fc 100644 --- a/target/i386/emulate/meson.build +++ b/target/i386/emulate/meson.build @@ -0,0 +1,5 @@ +i386_system_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files( + 'x86_decode.c', + 'x86_emu.c', + 'x86_flags.c', +)) diff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build index 05c3c8cf18b..519d190f0e6 100644 --- a/target/i386/hvf/meson.build +++ b/target/i386/hvf/meson.build @@ -2,10 +2,7 @@ i386_system_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files( 'hvf.c', 'x86.c', 'x86_cpuid.c', - 'x86_decode.c', 'x86_descr.c', - 'x86_emu.c', - 'x86_flags.c', 'x86_mmu.c', 'x86_task.c', 'x86hvf.c', -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 26/34] MAINTAINERS: add an entry for the x86 instruction emulator 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (24 preceding siblings ...) 2025-04-23 9:40 ` [PULL 25/34] target/i386: move x86 instruction emulator out of hvf Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 27/34] target/i386/emulate: remove flags_mask Paolo Bonzini ` (8 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu From: Wei Liu <liuwe@linux.microsoft.com> Add myself as a reviewer. Signed-off-by: Wei Liu <liuwe@linux.microsoft.com> Link: https://lore.kernel.org/r/1741377325-28175-15-git-send-email-liuwe@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d54b5578f88..67228401f06 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -534,6 +534,14 @@ S: Supported F: target/i386/whpx/ F: include/system/whpx.h +X86 Instruction Emulator +M: Cameron Esfahani <dirty@apple.com> +M: Roman Bolshakov <rbolshakov@ddn.com> +R: Phil Dennis-Jordan <phil@philjordan.eu> +R: Wei Liu <wei.liu@kernel.org> +S: Maintained +F: target/i386/emulate/ + Guest CPU Cores (Xen) --------------------- X86 Xen CPUs -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 27/34] target/i386/emulate: remove flags_mask 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (25 preceding siblings ...) 2025-04-23 9:40 ` [PULL 26/34] MAINTAINERS: add an entry for the x86 instruction emulator Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 28/34] i386/cpu: Consolidate the helper to get Host's vendor Paolo Bonzini ` (7 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Wei Liu, Richard Henderson The field is written but never read. Cc: Wei Liu <liuwe@linux.microsoft.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/emulate/x86_decode.h | 2 - target/i386/emulate/x86_decode.c | 864 +++++++++++++++---------------- 2 files changed, 424 insertions(+), 442 deletions(-) diff --git a/target/i386/emulate/x86_decode.h b/target/i386/emulate/x86_decode.h index 930d965164a..87cc728598d 100644 --- a/target/i386/emulate/x86_decode.h +++ b/target/i386/emulate/x86_decode.h @@ -295,8 +295,6 @@ typedef struct x86_decode { struct x86_modrm modrm; struct x86_decode_op op[4]; bool is_fpu; - uint32_t flags_mask; - } x86_decode; uint64_t sign(uint64_t val, int size); diff --git a/target/i386/emulate/x86_decode.c b/target/i386/emulate/x86_decode.c index ddd7b60bcfe..7fee2196878 100644 --- a/target/i386/emulate/x86_decode.c +++ b/target/i386/emulate/x86_decode.c @@ -429,7 +429,6 @@ struct decode_tbl { void (*decode_op4)(CPUX86State *env, struct x86_decode *decode, struct x86_decode_op *op4); void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode); - uint32_t flags_mask; }; struct decode_x87_tbl { @@ -445,7 +444,6 @@ struct decode_x87_tbl { void (*decode_op2)(CPUX86State *env, struct x86_decode *decode, struct x86_decode_op *op2); void (*decode_postfix)(CPUX86State *env, struct x86_decode *decode); - uint32_t flags_mask; }; struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL, @@ -470,7 +468,6 @@ static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode) 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; @@ -503,9 +500,6 @@ static void decode_ffgroup(CPUX86State *env, struct x86_decode *decode) X86_DECODE_CMD_INVL }; decode->cmd = group[decode->modrm.reg]; - if (decode->modrm.reg > 2) { - decode->flags_mask = 0; - } } static void decode_sldtgroup(CPUX86State *env, struct x86_decode *decode) @@ -693,733 +687,724 @@ static void decode_db_4(CPUX86State *env, struct x86_decode *decode) } -#define RFLAGS_MASK_NONE 0 -#define RFLAGS_MASK_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C) -#define RFLAGS_MASK_LAHF (CC_S | CC_Z | CC_A | CC_P | CC_C) -#define RFLAGS_MASK_CF (CC_C) -#define RFLAGS_MASK_IF (IF_MASK) -#define RFLAGS_MASK_TF (TF_MASK) -#define RFLAGS_MASK_DF (DF_MASK) -#define RFLAGS_MASK_ZF (CC_Z) - struct decode_tbl _1op_inst[] = { {0x0, X86_DECODE_CMD_ADD, 1, true, decode_modrm_rm, decode_modrm_reg, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL}, {0x1, X86_DECODE_CMD_ADD, 0, true, decode_modrm_rm, decode_modrm_reg, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL}, {0x2, X86_DECODE_CMD_ADD, 1, true, decode_modrm_reg, decode_modrm_rm, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL}, {0x3, X86_DECODE_CMD_ADD, 0, true, decode_modrm_reg, decode_modrm_rm, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL}, {0x4, X86_DECODE_CMD_ADD, 1, false, decode_rax, decode_imm8, NULL, NULL, - NULL, RFLAGS_MASK_OSZAPC}, + NULL}, {0x5, X86_DECODE_CMD_ADD, 0, false, decode_rax, decode_imm, NULL, NULL, - NULL, RFLAGS_MASK_OSZAPC}, + NULL}, {0x6, X86_DECODE_CMD_PUSH_SEG, 0, false, false, NULL, NULL, NULL, - decode_pushseg, RFLAGS_MASK_NONE}, + decode_pushseg}, {0x7, X86_DECODE_CMD_POP_SEG, 0, false, false, NULL, NULL, NULL, - decode_popseg, RFLAGS_MASK_NONE}, + decode_popseg}, {0x8, X86_DECODE_CMD_OR, 1, true, decode_modrm_rm, decode_modrm_reg, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL}, {0x9, X86_DECODE_CMD_OR, 0, true, decode_modrm_rm, decode_modrm_reg, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL}, {0xa, X86_DECODE_CMD_OR, 1, true, decode_modrm_reg, decode_modrm_rm, NULL, - NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL}, {0xb, X86_DECODE_CMD_OR, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xc, X86_DECODE_CMD_OR, 1, false, decode_rax, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xd, X86_DECODE_CMD_OR, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xe, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_pushseg}, {0xf, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_popseg}, {0x10, X86_DECODE_CMD_ADC, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x11, X86_DECODE_CMD_ADC, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x12, X86_DECODE_CMD_ADC, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x13, X86_DECODE_CMD_ADC, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x14, X86_DECODE_CMD_ADC, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x15, X86_DECODE_CMD_ADC, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x16, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_pushseg}, {0x17, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_popseg}, {0x18, X86_DECODE_CMD_SBB, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x19, X86_DECODE_CMD_SBB, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x1a, X86_DECODE_CMD_SBB, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x1b, X86_DECODE_CMD_SBB, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x1c, X86_DECODE_CMD_SBB, 1, false, decode_rax, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x1d, X86_DECODE_CMD_SBB, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x1e, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_pushseg}, {0x1f, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_popseg}, {0x20, X86_DECODE_CMD_AND, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x21, X86_DECODE_CMD_AND, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x22, X86_DECODE_CMD_AND, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x23, X86_DECODE_CMD_AND, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x24, X86_DECODE_CMD_AND, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x25, X86_DECODE_CMD_AND, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x28, X86_DECODE_CMD_SUB, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x29, X86_DECODE_CMD_SUB, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x2a, X86_DECODE_CMD_SUB, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x2b, X86_DECODE_CMD_SUB, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x2c, X86_DECODE_CMD_SUB, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x2d, X86_DECODE_CMD_SUB, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x2f, X86_DECODE_CMD_DAS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, NULL}, {0x30, X86_DECODE_CMD_XOR, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x31, X86_DECODE_CMD_XOR, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x32, X86_DECODE_CMD_XOR, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x33, X86_DECODE_CMD_XOR, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x34, X86_DECODE_CMD_XOR, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x35, X86_DECODE_CMD_XOR, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x38, X86_DECODE_CMD_CMP, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x39, X86_DECODE_CMD_CMP, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x3a, X86_DECODE_CMD_CMP, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x3b, X86_DECODE_CMD_CMP, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x3c, X86_DECODE_CMD_CMP, 1, false, decode_rax, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x3d, X86_DECODE_CMD_CMP, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x3f, X86_DECODE_CMD_AAS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, NULL}, {0x40, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_incgroup}, {0x41, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_incgroup}, {0x42, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_incgroup}, {0x43, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_incgroup}, {0x44, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_incgroup}, {0x45, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_incgroup}, {0x46, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_incgroup}, {0x47, X86_DECODE_CMD_INC, 0, false, - NULL, NULL, NULL, NULL, decode_incgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_incgroup}, {0x48, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_decgroup}, {0x49, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_decgroup}, {0x4a, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_decgroup}, {0x4b, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_decgroup}, {0x4c, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_decgroup}, {0x4d, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_decgroup}, {0x4e, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_decgroup}, {0x4f, X86_DECODE_CMD_DEC, 0, false, - NULL, NULL, NULL, NULL, decode_decgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_decgroup}, {0x50, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_pushgroup}, {0x51, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_pushgroup}, {0x52, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_pushgroup}, {0x53, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_pushgroup}, {0x54, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_pushgroup}, {0x55, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_pushgroup}, {0x56, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_pushgroup}, {0x57, X86_DECODE_CMD_PUSH, 0, false, - NULL, NULL, NULL, NULL, decode_pushgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_pushgroup}, {0x58, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_popgroup}, {0x59, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_popgroup}, {0x5a, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_popgroup}, {0x5b, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_popgroup}, {0x5c, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_popgroup}, {0x5d, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_popgroup}, {0x5e, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_popgroup}, {0x5f, X86_DECODE_CMD_POP, 0, false, - NULL, NULL, NULL, NULL, decode_popgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_popgroup}, {0x60, X86_DECODE_CMD_PUSHA, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x61, X86_DECODE_CMD_POPA, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x68, X86_DECODE_CMD_PUSH, 0, false, decode_imm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x6a, X86_DECODE_CMD_PUSH, 0, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x69, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, - decode_modrm_rm, decode_imm, NULL, NULL, RFLAGS_MASK_OSZAPC}, + decode_modrm_rm, decode_imm, NULL, NULL}, {0x6b, X86_DECODE_CMD_IMUL_3, 0, true, decode_modrm_reg, decode_modrm_rm, - decode_imm8_signed, NULL, NULL, RFLAGS_MASK_OSZAPC}, + decode_imm8_signed, NULL, NULL}, {0x6c, X86_DECODE_CMD_INS, 1, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x6d, X86_DECODE_CMD_INS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x6e, X86_DECODE_CMD_OUTS, 1, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x6f, X86_DECODE_CMD_OUTS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x70, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x71, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x72, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x73, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x74, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x75, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x76, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x77, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x78, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x79, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x7a, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x7b, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x7c, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x7d, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x7e, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x7f, X86_DECODE_CMD_JXX, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x80, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_addgroup}, {0x81, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm, - NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_addgroup}, {0x82, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_addgroup}, {0x83, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8_signed, - NULL, NULL, decode_addgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_addgroup}, {0x84, X86_DECODE_CMD_TST, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x85, X86_DECODE_CMD_TST, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0x86, X86_DECODE_CMD_XCHG, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x87, X86_DECODE_CMD_XCHG, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x88, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x89, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x8a, X86_DECODE_CMD_MOV, 1, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x8b, X86_DECODE_CMD_MOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x8c, X86_DECODE_CMD_MOV_FROM_SEG, 0, true, decode_modrm_rm, - decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + decode_modrm_reg, NULL, NULL, NULL}, {0x8d, X86_DECODE_CMD_LEA, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x8e, X86_DECODE_CMD_MOV_TO_SEG, 0, true, decode_modrm_reg, - decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + decode_modrm_rm, NULL, NULL, NULL}, {0x8f, X86_DECODE_CMD_POP, 0, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x90, X86_DECODE_CMD_NOP, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x91, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, + NULL, NULL, decode_xchgroup}, {0x92, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, + NULL, NULL, decode_xchgroup}, {0x93, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, + NULL, NULL, decode_xchgroup}, {0x94, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, + NULL, NULL, decode_xchgroup}, {0x95, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, + NULL, NULL, decode_xchgroup}, {0x96, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, + NULL, NULL, decode_xchgroup}, {0x97, X86_DECODE_CMD_XCHG, 0, false, NULL, decode_rax, - NULL, NULL, decode_xchgroup, RFLAGS_MASK_NONE}, + NULL, NULL, decode_xchgroup}, {0x98, X86_DECODE_CMD_CBW, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x99, X86_DECODE_CMD_CWD, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x9a, X86_DECODE_CMD_CALL_FAR, 0, false, NULL, - NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_farjmp}, {0x9c, X86_DECODE_CMD_PUSHF, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, /*{0x9d, X86_DECODE_CMD_POPF, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_POPF},*/ + NULL, NULL, NULL},*/ {0x9e, X86_DECODE_CMD_SAHF, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x9f, X86_DECODE_CMD_LAHF, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_LAHF}, + NULL, NULL, NULL}, {0xa0, X86_DECODE_CMD_MOV, 1, false, decode_rax, fetch_moffs, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xa1, X86_DECODE_CMD_MOV, 0, false, decode_rax, fetch_moffs, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xa2, X86_DECODE_CMD_MOV, 1, false, fetch_moffs, decode_rax, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xa3, X86_DECODE_CMD_MOV, 0, false, fetch_moffs, decode_rax, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xa4, X86_DECODE_CMD_MOVS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xa5, X86_DECODE_CMD_MOVS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xa6, X86_DECODE_CMD_CMPS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xa7, X86_DECODE_CMD_CMPS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xaa, X86_DECODE_CMD_STOS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xab, X86_DECODE_CMD_STOS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xac, X86_DECODE_CMD_LODS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xad, X86_DECODE_CMD_LODS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xae, X86_DECODE_CMD_SCAS, 1, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xaf, X86_DECODE_CMD_SCAS, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xa8, X86_DECODE_CMD_TST, 1, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xa9, X86_DECODE_CMD_TST, 0, false, decode_rax, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xb0, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup8}, {0xb1, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup8}, {0xb2, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup8}, {0xb3, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup8}, {0xb4, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup8}, {0xb5, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup8}, {0xb6, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup8}, {0xb7, X86_DECODE_CMD_MOV, 1, false, NULL, - NULL, NULL, NULL, decode_movgroup8, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup8}, {0xb8, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup}, {0xb9, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup}, {0xba, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup}, {0xbb, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup}, {0xbc, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup}, {0xbd, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup}, {0xbe, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup}, {0xbf, X86_DECODE_CMD_MOV, 0, false, NULL, - NULL, NULL, NULL, decode_movgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_movgroup}, {0xc0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_rotgroup}, {0xc1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_rotgroup}, {0xc2, X86_DECODE_RET_NEAR, 0, false, decode_imm16, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xc3, X86_DECODE_RET_NEAR, 0, false, NULL, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xc4, X86_DECODE_CMD_LES, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xc5, X86_DECODE_CMD_LDS, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xc6, X86_DECODE_CMD_MOV, 1, true, decode_modrm_rm, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xc7, X86_DECODE_CMD_MOV, 0, true, decode_modrm_rm, decode_imm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xc8, X86_DECODE_CMD_ENTER, 0, false, decode_imm16, decode_imm8, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xc9, X86_DECODE_CMD_LEAVE, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xca, X86_DECODE_RET_FAR, 0, false, decode_imm16, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xcb, X86_DECODE_RET_FAR, 0, false, decode_imm_0, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xcd, X86_DECODE_CMD_INT, 0, false, decode_imm8, NULL, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, /*{0xcf, X86_DECODE_CMD_IRET, 0, false, NULL, NULL, - NULL, NULL, NULL, RFLAGS_MASK_IRET},*/ + NULL, NULL, NULL},*/ {0xd0, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_imm_1, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_rotgroup}, {0xd1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm_1, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_rotgroup}, {0xd2, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, decode_rcx, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_rotgroup}, {0xd3, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_rcx, - NULL, NULL, decode_rotgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_rotgroup}, {0xd4, X86_DECODE_CMD_AAM, 0, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL}, {0xd5, X86_DECODE_CMD_AAD, 0, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL}, {0xd7, X86_DECODE_CMD_XLAT, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0xd8, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_x87_ins}, {0xd9, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_x87_ins}, {0xda, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_x87_ins}, {0xdb, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_x87_ins}, {0xdc, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_x87_ins}, {0xdd, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_x87_ins}, {0xde, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_x87_ins}, {0xdf, X86_DECODE_CMD_INVL, 0, true, NULL, - NULL, NULL, NULL, decode_x87_ins, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_x87_ins}, {0xe0, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xe1, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xe2, X86_DECODE_CMD_LOOP, 0, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xe3, X86_DECODE_CMD_JCXZ, 1, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0xe4, X86_DECODE_CMD_IN, 1, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xe5, X86_DECODE_CMD_IN, 0, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xe6, X86_DECODE_CMD_OUT, 1, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xe7, X86_DECODE_CMD_OUT, 0, false, decode_imm8, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xe8, X86_DECODE_CMD_CALL_NEAR, 0, false, decode_imm_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xe9, X86_DECODE_CMD_JMP_NEAR, 0, false, decode_imm_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xea, X86_DECODE_CMD_JMP_FAR, 0, false, - NULL, NULL, NULL, NULL, decode_farjmp, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_farjmp}, {0xeb, X86_DECODE_CMD_JMP_NEAR, 1, false, decode_imm8_signed, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xec, X86_DECODE_CMD_IN, 1, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0xed, X86_DECODE_CMD_IN, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0xee, X86_DECODE_CMD_OUT, 1, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0xef, X86_DECODE_CMD_OUT, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0xf4, X86_DECODE_CMD_HLT, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0xf5, X86_DECODE_CMD_CMC, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, + NULL, NULL, NULL, NULL, NULL}, {0xf6, X86_DECODE_CMD_INVL, 1, true, - NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_f7group}, {0xf7, X86_DECODE_CMD_INVL, 0, true, - NULL, NULL, NULL, NULL, decode_f7group, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, NULL, decode_f7group}, {0xf8, X86_DECODE_CMD_CLC, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, + NULL, NULL, NULL, NULL, NULL}, {0xf9, X86_DECODE_CMD_STC, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_CF}, + NULL, NULL, NULL, NULL, NULL}, {0xfa, X86_DECODE_CMD_CLI, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF}, + NULL, NULL, NULL, NULL, NULL}, {0xfb, X86_DECODE_CMD_STI, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_IF}, + NULL, NULL, NULL, NULL, NULL}, {0xfc, X86_DECODE_CMD_CLD, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF}, + NULL, NULL, NULL, NULL, NULL}, {0xfd, X86_DECODE_CMD_STD, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_DF}, + NULL, NULL, NULL, NULL, NULL}, {0xfe, X86_DECODE_CMD_INVL, 1, true, decode_modrm_rm, - NULL, NULL, NULL, decode_incgroup2, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, decode_incgroup2}, {0xff, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, - NULL, NULL, NULL, decode_ffgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL, decode_ffgroup}, }; struct decode_tbl _2op_inst[] = { {0x0, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, - NULL, NULL, NULL, decode_sldtgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_sldtgroup}, {0x1, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, - NULL, NULL, NULL, decode_lidtgroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_lidtgroup}, {0x6, X86_DECODE_CMD_CLTS, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_TF}, + NULL, NULL, NULL, NULL, NULL}, {0x9, X86_DECODE_CMD_WBINVD, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x18, X86_DECODE_CMD_PREFETCH, 0, true, - NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_x87_general}, {0x1f, X86_DECODE_CMD_NOP, 0, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x20, X86_DECODE_CMD_MOV_FROM_CR, 0, true, decode_modrm_rm, - decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + decode_modrm_reg, NULL, NULL, NULL}, {0x21, X86_DECODE_CMD_MOV_FROM_DR, 0, true, decode_modrm_rm, - decode_modrm_reg, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + decode_modrm_reg, NULL, NULL, NULL}, {0x22, X86_DECODE_CMD_MOV_TO_CR, 0, true, decode_modrm_reg, - decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + decode_modrm_rm, NULL, NULL, NULL}, {0x23, X86_DECODE_CMD_MOV_TO_DR, 0, true, decode_modrm_reg, - decode_modrm_rm, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + decode_modrm_rm, NULL, NULL, NULL}, {0x30, X86_DECODE_CMD_WRMSR, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x31, X86_DECODE_CMD_RDTSC, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x32, X86_DECODE_CMD_RDMSR, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0x40, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x41, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x42, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x43, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x44, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x45, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x46, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x47, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x48, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x49, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x4a, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x4b, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x4c, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x4d, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x4e, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x4f, X86_DECODE_CMD_CMOV, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0x77, X86_DECODE_CMD_EMMS, 0, false, - NULL, NULL, NULL, NULL, decode_x87_general, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_x87_general}, {0x82, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x83, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x84, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x85, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x86, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x87, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x88, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x89, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x8a, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x8b, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x8c, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x8d, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x8e, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x8f, X86_DECODE_CMD_JXX, 0, false, - NULL, NULL, NULL, NULL, decode_jxx, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_jxx}, {0x90, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x91, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x92, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x93, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x94, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x95, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x96, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x97, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x98, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x99, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x9a, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x9b, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x9c, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x9d, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x9e, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0x9f, X86_DECODE_CMD_SETXX, 1, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL}, {0xb0, X86_DECODE_CMD_CMPXCHG, 1, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xb1, X86_DECODE_CMD_CMPXCHG, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xb6, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xb7, X86_DECODE_CMD_MOVZX, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xb8, X86_DECODE_CMD_POPCNT, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xbe, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xbf, X86_DECODE_CMD_MOVSX, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xa0, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_pushseg}, {0xa1, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_popseg}, {0xa2, X86_DECODE_CMD_CPUID, 0, false, - NULL, NULL, NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, NULL}, {0xa3, X86_DECODE_CMD_BT, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_CF}, + NULL, NULL, NULL}, {0xa4, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg, - decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC}, + decode_imm8, NULL, NULL}, {0xa5, X86_DECODE_CMD_SHLD, 0, true, decode_modrm_rm, decode_modrm_reg, - decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC}, + decode_rcx, NULL, NULL}, {0xa8, X86_DECODE_CMD_PUSH_SEG, 0, false, false, - NULL, NULL, NULL, decode_pushseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_pushseg}, {0xa9, X86_DECODE_CMD_POP_SEG, 0, false, false, - NULL, NULL, NULL, decode_popseg, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_popseg}, {0xab, X86_DECODE_CMD_BTS, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_CF}, + NULL, NULL, NULL}, {0xac, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg, - decode_imm8, NULL, NULL, RFLAGS_MASK_OSZAPC}, + decode_imm8, NULL, NULL}, {0xad, X86_DECODE_CMD_SHRD, 0, true, decode_modrm_rm, decode_modrm_reg, - decode_rcx, NULL, NULL, RFLAGS_MASK_OSZAPC}, + decode_rcx, NULL, NULL}, {0xae, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, - NULL, NULL, NULL, decode_aegroup, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, decode_aegroup}, {0xaf, X86_DECODE_CMD_IMUL_2, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xb2, X86_DECODE_CMD_LSS, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_NONE}, + NULL, NULL, NULL}, {0xb3, X86_DECODE_CMD_BTR, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xba, X86_DECODE_CMD_INVL, 0, true, decode_modrm_rm, decode_imm8, - NULL, NULL, decode_btgroup, RFLAGS_MASK_OSZAPC}, + NULL, NULL, decode_btgroup}, {0xbb, X86_DECODE_CMD_BTC, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xbc, X86_DECODE_CMD_BSF, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xbd, X86_DECODE_CMD_BSR, 0, true, decode_modrm_reg, decode_modrm_rm, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xc1, X86_DECODE_CMD_XADD, 0, true, decode_modrm_rm, decode_modrm_reg, - NULL, NULL, NULL, RFLAGS_MASK_OSZAPC}, + NULL, NULL, NULL}, {0xc7, X86_DECODE_CMD_CMPXCHG8B, 0, true, decode_modrm_rm, - NULL, NULL, NULL, NULL, RFLAGS_MASK_ZF}, + NULL, NULL, NULL, NULL}, {0xc8, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_bswap}, {0xc9, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_bswap}, {0xca, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_bswap}, {0xcb, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_bswap}, {0xcc, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_bswap}, {0xcd, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_bswap}, {0xce, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_bswap}, {0xcf, X86_DECODE_CMD_BSWAP, 0, false, - NULL, NULL, NULL, NULL, decode_bswap, RFLAGS_MASK_NONE}, + NULL, NULL, NULL, NULL, decode_bswap}, }; struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL, @@ -1427,207 +1412,207 @@ struct decode_x87_tbl invl_inst_x87 = {0x0, 0, 0, 0, 0, false, false, NULL, 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}, + decode_x87_modrm_st0, decode_decode_x87_modrm_st0, NULL}, {0xd8, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL}, {0xd8, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, decode_x87_modrm_st0, - decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_decode_x87_modrm_st0, NULL}, {0xd8, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL}, {0xd8, 4, 3, X86_DECODE_CMD_FSUB, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL}, {0xd8, 4, 0, X86_DECODE_CMD_FSUB, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL}, {0xd8, 5, 3, X86_DECODE_CMD_FSUB, 10, true, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL}, {0xd8, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL}, {0xd8, 6, 3, X86_DECODE_CMD_FDIV, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL}, {0xd8, 6, 0, X86_DECODE_CMD_FDIV, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL}, {0xd8, 7, 3, X86_DECODE_CMD_FDIV, 10, true, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL}, {0xd8, 7, 0, X86_DECODE_CMD_FDIV, 4, true, false, decode_x87_modrm_st0, - decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL}, {0xd9, 0, 3, X86_DECODE_CMD_FLD, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL, NULL}, {0xd9, 0, 0, X86_DECODE_CMD_FLD, 4, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL, NULL}, {0xd9, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL}, {0xd9, 1, 0, X86_DECODE_CMD_INVL, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL, NULL}, {0xd9, 2, 3, X86_DECODE_CMD_INVL, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL, NULL}, {0xd9, 2, 0, X86_DECODE_CMD_FST, 4, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL, NULL}, {0xd9, 3, 3, X86_DECODE_CMD_INVL, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL, NULL}, {0xd9, 3, 0, X86_DECODE_CMD_FST, 4, false, true, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL, NULL}, {0xd9, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, - decode_x87_modrm_st0, NULL, decode_d9_4, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL, decode_d9_4}, {0xd9, 4, 0, X86_DECODE_CMD_INVL, 4, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_bytep, NULL, NULL}, {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}, + decode_x87_modrm_bytep, NULL, NULL}, {0xd9, 7, 3, X86_DECODE_CMD_FNSTCW, 2, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_bytep, NULL, NULL}, {0xd9, 7, 0, X86_DECODE_CMD_FNSTCW, 2, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_bytep, NULL, NULL}, {0xda, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xda, 0, 0, X86_DECODE_CMD_FADD, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL}, {0xda, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, - decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_decode_x87_modrm_st0, NULL}, {0xda, 1, 0, X86_DECODE_CMD_FMUL, 4, false, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL}, {0xda, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL}, {0xda, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL}, {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}, + decode_x87_modrm_intp, NULL}, {0xda, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, decode_x87_modrm_st0, - decode_decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_decode_x87_modrm_st0, NULL}, {0xda, 5, 0, X86_DECODE_CMD_FSUB, 4, true, false, decode_x87_modrm_st0, - decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL}, {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}, + decode_x87_modrm_intp, NULL}, {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}, + decode_x87_modrm_intp, NULL}, {0xdb, 0, 3, X86_DECODE_CMD_FCMOV, 10, false, false, decode_x87_modrm_st0, - decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL}, {0xdb, 0, 0, X86_DECODE_CMD_FLD, 4, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL, NULL}, {0xdb, 1, 3, X86_DECODE_CMD_FCMOV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdb, 2, 3, X86_DECODE_CMD_FCMOV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdb, 2, 0, X86_DECODE_CMD_FST, 4, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL, NULL}, {0xdb, 3, 3, X86_DECODE_CMD_FCMOV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdb, 3, 0, X86_DECODE_CMD_FST, 4, false, true, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL, NULL}, {0xdb, 4, 3, X86_DECODE_CMD_INVL, 10, false, false, NULL, NULL, - decode_db_4, RFLAGS_MASK_NONE}, + decode_db_4}, {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}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdb, 5, 0, X86_DECODE_CMD_FLD, 10, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL, NULL}, {0xdb, 7, 0, X86_DECODE_CMD_FST, 10, false, true, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL, NULL}, {0xdc, 0, 3, X86_DECODE_CMD_FADD, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdc, 0, 0, X86_DECODE_CMD_FADD, 8, false, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, {0xdc, 1, 3, X86_DECODE_CMD_FMUL, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdc, 1, 0, X86_DECODE_CMD_FMUL, 8, false, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, {0xdc, 4, 3, X86_DECODE_CMD_FSUB, 10, true, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdc, 4, 0, X86_DECODE_CMD_FSUB, 8, false, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, {0xdc, 5, 3, X86_DECODE_CMD_FSUB, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdc, 5, 0, X86_DECODE_CMD_FSUB, 8, true, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, {0xdc, 6, 3, X86_DECODE_CMD_FDIV, 10, true, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdc, 6, 0, X86_DECODE_CMD_FDIV, 8, false, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, {0xdc, 7, 3, X86_DECODE_CMD_FDIV, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdc, 7, 0, X86_DECODE_CMD_FDIV, 8, true, false, - decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_floatp, NULL}, {0xdd, 0, 0, X86_DECODE_CMD_FLD, 8, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL, NULL}, {0xdd, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdd, 2, 3, X86_DECODE_CMD_FST, 10, false, false, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL, NULL}, {0xdd, 2, 0, X86_DECODE_CMD_FST, 8, false, false, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL, NULL}, {0xdd, 3, 3, X86_DECODE_CMD_FST, 10, false, true, - decode_x87_modrm_st0, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, NULL, NULL}, {0xdd, 3, 0, X86_DECODE_CMD_FST, 8, false, true, - decode_x87_modrm_floatp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_floatp, NULL, NULL}, {0xdd, 4, 3, X86_DECODE_CMD_FUCOM, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdd, 4, 0, X86_DECODE_CMD_FRSTOR, 8, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_bytep, NULL, NULL}, {0xdd, 5, 3, X86_DECODE_CMD_FUCOM, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdd, 7, 0, X86_DECODE_CMD_FNSTSW, 0, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_bytep, NULL, NULL}, {0xdd, 7, 3, X86_DECODE_CMD_FNSTSW, 0, false, false, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_bytep, NULL, NULL}, {0xde, 0, 3, X86_DECODE_CMD_FADD, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xde, 0, 0, X86_DECODE_CMD_FADD, 2, false, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, {0xde, 1, 3, X86_DECODE_CMD_FMUL, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xde, 1, 0, X86_DECODE_CMD_FMUL, 2, false, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, {0xde, 4, 3, X86_DECODE_CMD_FSUB, 10, true, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xde, 4, 0, X86_DECODE_CMD_FSUB, 2, false, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, {0xde, 5, 3, X86_DECODE_CMD_FSUB, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xde, 5, 0, X86_DECODE_CMD_FSUB, 2, true, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, {0xde, 6, 3, X86_DECODE_CMD_FDIV, 10, true, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xde, 6, 0, X86_DECODE_CMD_FDIV, 2, false, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, {0xde, 7, 3, X86_DECODE_CMD_FDIV, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xde, 7, 0, X86_DECODE_CMD_FDIV, 2, true, false, - decode_x87_modrm_st0, decode_x87_modrm_intp, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_intp, NULL}, {0xdf, 0, 0, X86_DECODE_CMD_FLD, 2, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL, NULL}, {0xdf, 1, 3, X86_DECODE_CMD_FXCH, 10, false, false, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdf, 2, 3, X86_DECODE_CMD_FST, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdf, 2, 0, X86_DECODE_CMD_FST, 2, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL, NULL}, {0xdf, 3, 3, X86_DECODE_CMD_FST, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdf, 3, 0, X86_DECODE_CMD_FST, 2, false, true, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL, NULL}, {0xdf, 4, 3, X86_DECODE_CMD_FNSTSW, 2, false, true, - decode_x87_modrm_bytep, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_bytep, NULL, NULL}, {0xdf, 5, 3, X86_DECODE_CMD_FUCOMI, 10, false, true, - decode_x87_modrm_st0, decode_x87_modrm_st0, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_st0, decode_x87_modrm_st0, NULL}, {0xdf, 5, 0, X86_DECODE_CMD_FLD, 8, false, false, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL, NULL}, {0xdf, 7, 0, X86_DECODE_CMD_FST, 8, false, true, - decode_x87_modrm_intp, NULL, NULL, RFLAGS_MASK_NONE}, + decode_x87_modrm_intp, NULL, NULL}, }; void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode, @@ -2045,7 +2030,6 @@ static inline void decode_opcode_general(CPUX86State *env, if (inst_decoder->operand_size) { decode->operand_size = inst_decoder->operand_size; } - decode->flags_mask = inst_decoder->flags_mask; if (inst_decoder->is_modrm) { decode_modrm(env, decode); -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 28/34] i386/cpu: Consolidate the helper to get Host's vendor 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (26 preceding siblings ...) 2025-04-23 9:40 ` [PULL 27/34] target/i386/emulate: remove flags_mask Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:40 ` [PULL 29/34] rust/hpet: convert num_timers to u8 type Paolo Bonzini ` (6 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Zhao Liu, Dongli Zhang From: Zhao Liu <zhao1.liu@intel.com> Extend host_cpu_vendor_fms() to help more cases to get Host's vendor information. Cc: Dongli Zhang <dongli.zhang@oracle.com> Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250410075619.145792-1-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- target/i386/host-cpu.c | 10 ++++++---- target/i386/kvm/vmsr_energy.c | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c index 3e4e85e729c..072731a4dd2 100644 --- a/target/i386/host-cpu.c +++ b/target/i386/host-cpu.c @@ -109,9 +109,13 @@ void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepping) { uint32_t eax, ebx, ecx, edx; - host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx); + host_cpuid(0x0, 0, NULL, &ebx, &ecx, &edx); x86_cpu_vendor_words2str(vendor, ebx, edx, ecx); + if (!family && !model && !stepping) { + return; + } + host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx); if (family) { *family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF); @@ -129,11 +133,9 @@ void host_cpu_instance_init(X86CPU *cpu) X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); if (xcc->model) { - uint32_t ebx = 0, ecx = 0, edx = 0; char vendor[CPUID_VENDOR_SZ + 1]; - host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); - x86_cpu_vendor_words2str(vendor, ebx, edx, ecx); + host_cpu_vendor_fms(vendor, NULL, NULL, NULL); object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); } } diff --git a/target/i386/kvm/vmsr_energy.c b/target/i386/kvm/vmsr_energy.c index 31508d4e77a..f499ec6e8b0 100644 --- a/target/i386/kvm/vmsr_energy.c +++ b/target/i386/kvm/vmsr_energy.c @@ -29,10 +29,9 @@ char *vmsr_compute_default_paths(void) bool is_host_cpu_intel(void) { - int family, model, stepping; char vendor[CPUID_VENDOR_SZ + 1]; - host_cpu_vendor_fms(vendor, &family, &model, &stepping); + host_cpu_vendor_fms(vendor, NULL, NULL, NULL); return g_str_equal(vendor, CPUID_VENDOR_INTEL); } -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 29/34] rust/hpet: convert num_timers to u8 type 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (27 preceding siblings ...) 2025-04-23 9:40 ` [PULL 28/34] i386/cpu: Consolidate the helper to get Host's vendor Paolo Bonzini @ 2025-04-23 9:40 ` Paolo Bonzini 2025-04-23 9:41 ` [PULL 30/34] rust/hpet: convert HPETTimer index " Paolo Bonzini ` (5 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:40 UTC (permalink / raw) To: qemu-devel; +Cc: Zhao Liu From: Zhao Liu <zhao1.liu@intel.com> The C version of HPET uses the uint8_t type for num_timers, and usize type in Rust version will break migration between the C and Rust versions. So convert num_timers' type to u8 (consistent with the C version of HPET) to make it friendly for vmstate support. Note the commit 7bda68e8e2b0 ("qdev, rust/hpet: fix type of HPET 'timers property") supports the usize type property, but the uint8 property has to be re-supported now. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250414144943.1112885-7-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- rust/hw/timer/hpet/src/hpet.rs | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index 3ae3ec25f17..1afa891362f 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -12,7 +12,7 @@ use qemu_api::{ bindings::{ address_space_memory, address_space_stl_le, qdev_prop_bit, qdev_prop_bool, - qdev_prop_uint32, qdev_prop_usize, + qdev_prop_uint32, qdev_prop_uint8, }, c_str, cell::{BqlCell, BqlRefCell}, @@ -34,9 +34,9 @@ const HPET_REG_SPACE_LEN: u64 = 0x400; // 1024 bytes /// Minimum recommended hardware implementation. -const HPET_MIN_TIMERS: usize = 3; +const HPET_MIN_TIMERS: u8 = 3; /// Maximum timers in each timer block. -const HPET_MAX_TIMERS: usize = 32; +const HPET_MAX_TIMERS: u8 = 32; /// Flags that HPETState.flags supports. const HPET_FLAG_MSI_SUPPORT_SHIFT: usize = 0; @@ -559,14 +559,19 @@ pub struct HPETState { /// HPET timer array managed by this timer block. #[doc(alias = "timer")] - timers: [BqlRefCell<HPETTimer>; HPET_MAX_TIMERS], - num_timers: BqlCell<usize>, + timers: [BqlRefCell<HPETTimer>; HPET_MAX_TIMERS as usize], + num_timers: BqlCell<u8>, /// Instance id (HPET timer block ID). hpet_id: BqlCell<usize>, } impl HPETState { + // Get num_timers with `usize` type, which is useful to play with array index. + fn get_num_timers(&self) -> usize { + self.num_timers.get().into() + } + const fn has_msi_flag(&self) -> bool { self.flags & (1 << HPET_FLAG_MSI_SUPPORT_SHIFT) != 0 } @@ -628,7 +633,7 @@ fn set_cfg_reg(&self, shift: u32, len: u32, val: u64) { self.hpet_offset .set(ticks_to_ns(self.counter.get()) - CLOCK_VIRTUAL.get_ns()); - for timer in self.timers.iter().take(self.num_timers.get()) { + for timer in self.timers.iter().take(self.get_num_timers()) { let mut t = timer.borrow_mut(); if t.is_int_enabled() && t.is_int_active() { @@ -640,7 +645,7 @@ fn set_cfg_reg(&self, shift: u32, len: u32, val: u64) { // Halt main counter and disable interrupt generation. self.counter.set(self.get_ticks()); - for timer in self.timers.iter().take(self.num_timers.get()) { + for timer in self.timers.iter().take(self.get_num_timers()) { timer.borrow_mut().del_timer(); } } @@ -663,7 +668,7 @@ fn set_int_status_reg(&self, shift: u32, _len: u32, val: u64) { let new_val = val << shift; let cleared = new_val & self.int_status.get(); - for (index, timer) in self.timers.iter().take(self.num_timers.get()).enumerate() { + for (index, timer) in self.timers.iter().take(self.get_num_timers()).enumerate() { if cleared & (1 << index) != 0 { timer.borrow_mut().update_irq(false); } @@ -737,7 +742,7 @@ fn realize(&self) { 1 << HPET_CAP_COUNT_SIZE_CAP_SHIFT | 1 << HPET_CAP_LEG_RT_CAP_SHIFT | HPET_CAP_VENDER_ID_VALUE << HPET_CAP_VENDER_ID_SHIFT | - ((self.num_timers.get() - 1) as u64) << HPET_CAP_NUM_TIM_SHIFT | // indicate the last timer + ((self.get_num_timers() - 1) as u64) << HPET_CAP_NUM_TIM_SHIFT | // indicate the last timer (HPET_CLK_PERIOD * FS_PER_NS) << HPET_CAP_CNT_CLK_PERIOD_SHIFT, // 10 ns ); @@ -746,7 +751,7 @@ fn realize(&self) { } fn reset_hold(&self, _type: ResetType) { - for timer in self.timers.iter().take(self.num_timers.get()) { + for timer in self.timers.iter().take(self.get_num_timers()) { timer.borrow_mut().reset(); } @@ -774,7 +779,7 @@ fn decode(&self, mut addr: hwaddr, size: u32) -> HPETAddrDecode { GlobalRegister::try_from(addr).map(HPETRegister::Global) } else { let timer_id: usize = ((addr - 0x100) / 0x20) as usize; - if timer_id <= self.num_timers.get() { + if timer_id <= self.get_num_timers() { // TODO: Add trace point - trace_hpet_ram_[read|write]_timer_id(timer_id) TimerRegister::try_from(addr & 0x18) .map(|reg| HPETRegister::Timer(&self.timers[timer_id], reg)) @@ -859,8 +864,8 @@ impl ObjectImpl for HPETState { c_str!("timers"), HPETState, num_timers, - unsafe { &qdev_prop_usize }, - usize, + unsafe { &qdev_prop_uint8 }, + u8, default = HPET_MIN_TIMERS ), qemu_api::define_property!( -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 30/34] rust/hpet: convert HPETTimer index to u8 type 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (28 preceding siblings ...) 2025-04-23 9:40 ` [PULL 29/34] rust/hpet: convert num_timers to u8 type Paolo Bonzini @ 2025-04-23 9:41 ` Paolo Bonzini 2025-04-23 9:41 ` [PULL 31/34] rust/hpet: Fix a clippy error Paolo Bonzini ` (4 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:41 UTC (permalink / raw) To: qemu-devel; +Cc: Zhao Liu From: Zhao Liu <zhao1.liu@intel.com> The C version of HPET uses the uint8_t type for timer index ("tn"), and usize type in Rust version will break migration between the C and Rust versions. So convert HPETTimer index' type to u8 (consistent with the C version of HPET) to make it friendly for vmstate support. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250414144943.1112885-8-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- rust/hw/timer/hpet/src/hpet.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index 1afa891362f..dc8a23f29d9 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -184,7 +184,7 @@ fn timer_handler(timer_cell: &BqlRefCell<HPETTimer>) { pub struct HPETTimer { /// timer N index within the timer block (`HPETState`) #[doc(alias = "tn")] - index: usize, + index: u8, qemu_timer: Timer, /// timer block abstraction containing this timer state: NonNull<HPETState>, @@ -210,7 +210,7 @@ pub struct HPETTimer { } impl HPETTimer { - fn init(&mut self, index: usize, state: &HPETState) { + fn init(&mut self, index: u8, state: &HPETState) { *self = HPETTimer { index, // SAFETY: the HPETTimer will only be used after the timer @@ -235,7 +235,7 @@ fn init(&mut self, index: usize, state: &HPETState) { Timer::NS, 0, timer_handler, - &state.timers[self.index], + &state.timers[self.index as usize], ) } @@ -246,7 +246,7 @@ fn get_state(&self) -> &HPETState { } fn is_int_active(&self) -> bool { - self.get_state().is_timer_int_active(self.index) + self.get_state().is_timer_int_active(self.index.into()) } const fn is_fsb_route_enabled(&self) -> bool { @@ -611,7 +611,7 @@ fn handle_legacy_irq(&self, irq: u32, level: u32) { fn init_timer(&self) { for (index, timer) in self.timers.iter().enumerate() { - timer.borrow_mut().init(index, self); + timer.borrow_mut().init(index.try_into().unwrap(), self); } } -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 31/34] rust/hpet: Fix a clippy error 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (29 preceding siblings ...) 2025-04-23 9:41 ` [PULL 30/34] rust/hpet: convert HPETTimer index " Paolo Bonzini @ 2025-04-23 9:41 ` Paolo Bonzini 2025-04-23 9:41 ` [PULL 32/34] rust/vmstate_test: Fix typo in test_vmstate_macro_array_of_pointer_wrapped() Paolo Bonzini ` (3 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:41 UTC (permalink / raw) To: qemu-devel; +Cc: Zhao Liu From: Zhao Liu <zhao1.liu@intel.com> Carge clippy complained about: error: casts from `u8` to `u32` can be expressed infallibly using `From` So use `From` to convert `u8` to `u32`. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250414144943.1112885-10-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- rust/hw/timer/hpet/src/hpet.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index dc8a23f29d9..cbd2ed4f6bf 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -353,7 +353,7 @@ fn update_irq(&mut self, set: bool) { // still operate and generate appropriate status bits, but // will not cause an interrupt" self.get_state() - .update_int_status(self.index as u32, set && self.is_int_level_triggered()); + .update_int_status(self.index.into(), set && self.is_int_level_triggered()); self.set_irq(set); } -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 32/34] rust/vmstate_test: Fix typo in test_vmstate_macro_array_of_pointer_wrapped() 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (30 preceding siblings ...) 2025-04-23 9:41 ` [PULL 31/34] rust/hpet: Fix a clippy error Paolo Bonzini @ 2025-04-23 9:41 ` Paolo Bonzini 2025-04-23 9:41 ` [PULL 33/34] rust/hw/char/pl011: Extract extract DR read logic into separate function Paolo Bonzini ` (2 subsequent siblings) 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:41 UTC (permalink / raw) To: qemu-devel; +Cc: Zhao Liu From: Zhao Liu <zhao1.liu@intel.com> test_vmstate_macro_array_of_pointer_wrapped() tests the 3rd element, so fix the index. Signed-off-by: Zhao Liu <zhao1.liu@intel.com> Link: https://lore.kernel.org/r/20250414144943.1112885-5-zhao1.liu@intel.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- rust/qemu-api/tests/vmstate_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/qemu-api/tests/vmstate_tests.rs b/rust/qemu-api/tests/vmstate_tests.rs index b8d8b45b19d..8b93492a689 100644 --- a/rust/qemu-api/tests/vmstate_tests.rs +++ b/rust/qemu-api/tests/vmstate_tests.rs @@ -383,12 +383,12 @@ fn test_vmstate_macro_array_of_pointer_wrapped() { ); assert_eq!(foo_fields[3].offset, (FOO_ARRAY_MAX + 2) * PTR_SIZE); assert_eq!(foo_fields[3].num_offset, 0); - assert_eq!(foo_fields[2].info, unsafe { &vmstate_info_uint8 }); + assert_eq!(foo_fields[3].info, unsafe { &vmstate_info_uint8 }); assert_eq!(foo_fields[3].version_id, 0); assert_eq!(foo_fields[3].size, PTR_SIZE); assert_eq!(foo_fields[3].num, FOO_ARRAY_MAX as i32); assert_eq!( - foo_fields[2].flags.0, + foo_fields[3].flags.0, VMStateFlags::VMS_ARRAY.0 | VMStateFlags::VMS_ARRAY_OF_POINTER.0 ); assert!(foo_fields[3].vmsd.is_null()); -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 33/34] rust/hw/char/pl011: Extract extract DR read logic into separate function 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (31 preceding siblings ...) 2025-04-23 9:41 ` [PULL 32/34] rust/vmstate_test: Fix typo in test_vmstate_macro_array_of_pointer_wrapped() Paolo Bonzini @ 2025-04-23 9:41 ` Paolo Bonzini 2025-04-23 9:41 ` [PULL 34/34] rust/hw/char/pl011: Extract DR write " Paolo Bonzini 2025-04-23 17:58 ` [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Stefan Hajnoczi 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:41 UTC (permalink / raw) To: qemu-devel; +Cc: Rakesh Jeyasingh From: Rakesh Jeyasingh <rakeshjb010@gmail.com> - Split `read()` DR case into `read_data_register()` Signed-off-by: Rakesh Jeyasingh <rakeshjb010@gmail.com> Link: https://lore.kernel.org/r/20250407181327.171563-2-rakeshjb010@gmail.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- rust/hw/char/pl011/src/device.rs | 39 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index bf88e0b00a0..87153cdae13 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -190,25 +190,7 @@ pub(self) fn read(&mut self, offset: RegisterOffset) -> (bool, u32) { let mut update = false; let result = match offset { - DR => { - self.flags.set_receive_fifo_full(false); - let c = self.read_fifo[self.read_pos]; - if self.read_count > 0 { - self.read_count -= 1; - self.read_pos = (self.read_pos + 1) & (self.fifo_depth() - 1); - } - if self.read_count == 0 { - self.flags.set_receive_fifo_empty(true); - } - if self.read_count + 1 == self.read_trigger { - self.int_level &= !Interrupt::RX.0; - } - // Update error bits. - self.receive_status_error_clear.set_from_data(c); - // Must call qemu_chr_fe_accept_input - update = true; - u32::from(c) - } + DR => self.read_data_register(&mut update), RSR => u32::from(self.receive_status_error_clear), FR => u32::from(self.flags), FBRD => self.fbrd, @@ -306,6 +288,25 @@ pub(self) fn write( false } + fn read_data_register(&mut self, update: &mut bool) -> u32 { + self.flags.set_receive_fifo_full(false); + let c = self.read_fifo[self.read_pos]; + + if self.read_count > 0 { + self.read_count -= 1; + self.read_pos = (self.read_pos + 1) & (self.fifo_depth() - 1); + } + if self.read_count == 0 { + self.flags.set_receive_fifo_empty(true); + } + if self.read_count + 1 == self.read_trigger { + self.int_level &= !Interrupt::RX.0; + } + self.receive_status_error_clear.set_from_data(c); + *update = true; + u32::from(c) + } + #[inline] #[must_use] fn loopback_tx(&mut self, value: registers::Data) -> bool { -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PULL 34/34] rust/hw/char/pl011: Extract DR write logic into separate function 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (32 preceding siblings ...) 2025-04-23 9:41 ` [PULL 33/34] rust/hw/char/pl011: Extract extract DR read logic into separate function Paolo Bonzini @ 2025-04-23 9:41 ` Paolo Bonzini 2025-04-23 17:58 ` [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Stefan Hajnoczi 34 siblings, 0 replies; 36+ messages in thread From: Paolo Bonzini @ 2025-04-23 9:41 UTC (permalink / raw) To: qemu-devel; +Cc: Rakesh Jeyasingh From: Rakesh Jeyasingh <rakeshjb010@gmail.com> - Split `write()` DR case into `write_data_register()` Signed-off-by: Rakesh Jeyasingh <rakeshjb010@gmail.com> Link: https://lore.kernel.org/r/20250407181327.171563-3-rakeshjb010@gmail.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- rust/hw/char/pl011/src/device.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 87153cdae13..bb2a0f207a5 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -221,12 +221,7 @@ pub(self) fn write( // eprintln!("write offset {offset} value {value}"); use RegisterOffset::*; match offset { - DR => { - // interrupts always checked - let _ = self.loopback_tx(value.into()); - self.int_level |= Interrupt::TX.0; - return true; - } + DR => return self.write_data_register(value), RSR => { self.receive_status_error_clear = 0.into(); } @@ -307,6 +302,13 @@ fn read_data_register(&mut self, update: &mut bool) -> u32 { u32::from(c) } + fn write_data_register(&mut self, value: u32) -> bool { + // interrupts always checked + let _ = self.loopback_tx(value.into()); + self.int_level |= Interrupt::TX.0; + true + } + #[inline] #[must_use] fn loopback_tx(&mut self, value: registers::Data) -> bool { -- 2.49.0 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini ` (33 preceding siblings ...) 2025-04-23 9:41 ` [PULL 34/34] rust/hw/char/pl011: Extract DR write " Paolo Bonzini @ 2025-04-23 17:58 ` Stefan Hajnoczi 34 siblings, 0 replies; 36+ messages in thread From: Stefan Hajnoczi @ 2025-04-23 17:58 UTC (permalink / raw) To: Paolo Bonzini; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 116 bytes --] Applied, thanks. Please update the changelog at https://wiki.qemu.org/ChangeLog/10.0 for any user-visible changes. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2025-04-23 17:58 UTC | newest] Thread overview: 36+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-04-23 9:40 [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Paolo Bonzini 2025-04-23 9:40 ` [PULL 01/34] scsi: add conversion from ENODEV to sense Paolo Bonzini 2025-04-23 9:40 ` [PULL 02/34] target/i386: Fix model number of Zhaoxin YongFeng vCPU template Paolo Bonzini 2025-04-23 9:40 ` [PULL 03/34] target/i386: Reset parked vCPUs together with the online ones Paolo Bonzini 2025-04-23 9:40 ` [PULL 04/34] target/i386/hvf: fix lflags_to_rflags Paolo Bonzini 2025-04-23 9:40 ` [PULL 05/34] target/i386: special case ADC/SBB x,0 and SBB x,x Paolo Bonzini 2025-04-23 9:40 ` [PULL 06/34] target/i386: tcg: remove tmp0 and tmp4 from SHLD/SHRD Paolo Bonzini 2025-04-23 9:40 ` [PULL 07/34] target/i386: tcg: remove subf from SHLD/SHRD expansion Paolo Bonzini 2025-04-23 9:40 ` [PULL 08/34] target/i386: tcg: remove tmp0 Paolo Bonzini 2025-04-23 9:40 ` [PULL 09/34] target/i386: tcg: remove some more uses of temporaries Paolo Bonzini 2025-04-23 9:40 ` [PULL 10/34] target/i386: tcg: simplify computation of AF after INC/DEC Paolo Bonzini 2025-04-23 9:40 ` [PULL 11/34] target/i386: emulate: microoptimize and explain ADD_COUT_VEC/SUB_COUT_VEC Paolo Bonzini 2025-04-23 9:40 ` [PULL 12/34] target/i386: tcg: use cout to commonize add/adc/sub/sbb cases Paolo Bonzini 2025-04-23 9:40 ` [PULL 13/34] target/i386/hvf: introduce x86_emul_ops Paolo Bonzini 2025-04-23 9:40 ` [PULL 14/34] target/i386/hvf: remove HVF specific calls from x86_decode.c Paolo Bonzini 2025-04-23 9:40 ` [PULL 15/34] target/i386/hvf: provide and use handle_io in emul_ops Paolo Bonzini 2025-04-23 9:40 ` [PULL 16/34] target/i386: rename hvf_mmio_buf to emu_mmio_buf Paolo Bonzini 2025-04-23 9:40 ` [PULL 17/34] target/i386/hvf: use emul_ops->read_mem in x86_emu.c Paolo Bonzini 2025-04-23 9:40 ` [PULL 18/34] target/i386/hvf: provide and use write_mem in emul_ops Paolo Bonzini 2025-04-23 9:40 ` [PULL 19/34] target/i386/hvf: provide and use simulate_{wrmsr, rdmsr} " Paolo Bonzini 2025-04-23 9:40 ` [PULL 20/34] target/i386: rename lazy flags field and its type Paolo Bonzini 2025-04-23 9:40 ` [PULL 21/34] target/i386/hvf: drop unused headers Paolo Bonzini 2025-04-23 9:40 ` [PULL 22/34] target/i386/hvf: rename some include guards Paolo Bonzini 2025-04-23 9:40 ` [PULL 23/34] target/i386: add a directory for x86 instruction emulator Paolo Bonzini 2025-04-23 9:40 ` [PULL 24/34] target/i386/emulate: add a panic.h Paolo Bonzini 2025-04-23 9:40 ` [PULL 25/34] target/i386: move x86 instruction emulator out of hvf Paolo Bonzini 2025-04-23 9:40 ` [PULL 26/34] MAINTAINERS: add an entry for the x86 instruction emulator Paolo Bonzini 2025-04-23 9:40 ` [PULL 27/34] target/i386/emulate: remove flags_mask Paolo Bonzini 2025-04-23 9:40 ` [PULL 28/34] i386/cpu: Consolidate the helper to get Host's vendor Paolo Bonzini 2025-04-23 9:40 ` [PULL 29/34] rust/hpet: convert num_timers to u8 type Paolo Bonzini 2025-04-23 9:41 ` [PULL 30/34] rust/hpet: convert HPETTimer index " Paolo Bonzini 2025-04-23 9:41 ` [PULL 31/34] rust/hpet: Fix a clippy error Paolo Bonzini 2025-04-23 9:41 ` [PULL 32/34] rust/vmstate_test: Fix typo in test_vmstate_macro_array_of_pointer_wrapped() Paolo Bonzini 2025-04-23 9:41 ` [PULL 33/34] rust/hw/char/pl011: Extract extract DR read logic into separate function Paolo Bonzini 2025-04-23 9:41 ` [PULL 34/34] rust/hw/char/pl011: Extract DR write " Paolo Bonzini 2025-04-23 17:58 ` [PULL 00/34] i386, Rust, SCSI changes for 2025-04-23 Stefan Hajnoczi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).