diff options
112 files changed, 1881 insertions, 1963 deletions
@@ -1004,6 +1004,25 @@ for opt do esac done +if ! has $python; then + error_exit "Python not found. Use --python=/path/to/python" +fi + +# Note that if the Python conditional here evaluates True we will exit +# with status 1 which is a shell 'false' value. +if ! $python -c 'import sys; sys.exit(sys.version_info < (2,4) or sys.version_info >= (3,))'; then + error_exit "Cannot use '$python', Python 2.4 or later is required." \ + "Note that Python 3 or later is not yet supported." \ + "Use --python=/path/to/python to specify a supported Python." +fi + +# The -B switch was added in Python 2.6. +# If it is supplied, compiled files are not written. +# Use it for Python versions which support it. +if $python -B -c 'import sys; sys.exit(0)' 2>/dev/null; then + python="$python -B" +fi + case "$cpu" in ppc) CPU_CFLAGS="-m32" @@ -1074,169 +1093,169 @@ cat << EOF Usage: configure [options] Options: [defaults in brackets after descriptions] +Standard options: + --help print this message + --prefix=PREFIX install in PREFIX [$prefix] + --interp-prefix=PREFIX where to find shared libraries, etc. + use %M for cpu name [$interp_prefix] + --target-list=LIST set target list (default: build everything) +$(echo Available targets: $default_target_list | \ + fold -s -w 53 | sed -e 's/^/ /') + +Advanced options (experts only): + --source-path=PATH path of source code [$source_path] + --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix] + --cc=CC use C compiler CC [$cc] + --iasl=IASL use ACPI compiler IASL [$iasl] + --host-cc=CC use C compiler CC [$host_cc] for code run at + build time + --cxx=CXX use C++ compiler CXX [$cxx] + --objcc=OBJCC use Objective-C compiler OBJCC [$objcc] + --extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS + --extra-ldflags=LDFLAGS append extra linker flags LDFLAGS + --make=MAKE use specified make [$make] + --install=INSTALL use specified install [$install] + --python=PYTHON use specified python [$python] + --smbd=SMBD use specified smbd [$smbd] + --static enable static build [$static] + --mandir=PATH install man pages in PATH + --datadir=PATH install firmware in PATH$confsuffix + --docdir=PATH install documentation in PATH$confsuffix + --bindir=PATH install binaries in PATH + --libdir=PATH install libraries in PATH + --sysconfdir=PATH install config in PATH$confsuffix + --localstatedir=PATH install local state in PATH (set at runtime on win32) + --with-confsuffix=SUFFIX suffix for QEMU data inside datadir and sysconfdir [$confsuffix] + --enable-debug-tcg enable TCG debugging + --disable-debug-tcg disable TCG debugging (default) + --enable-debug-info enable debugging information (default) + --disable-debug-info disable debugging information + --enable-debug enable common debug build options + --enable-sparse enable sparse checker + --disable-sparse disable sparse checker (default) + --disable-strip disable stripping binaries + --disable-werror disable compilation abort on warning + --disable-sdl disable SDL + --enable-sdl enable SDL + --disable-gtk disable gtk UI + --enable-gtk enable gtk UI + --disable-virtfs disable VirtFS + --enable-virtfs enable VirtFS + --disable-vnc disable VNC + --enable-vnc enable VNC + --disable-cocoa disable Cocoa (Mac OS X only) + --enable-cocoa enable Cocoa (default on Mac OS X) + --audio-drv-list=LIST set audio drivers list: + Available drivers: $audio_possible_drivers + --block-drv-whitelist=L Same as --block-drv-rw-whitelist=L + --block-drv-rw-whitelist=L + set block driver read-write whitelist + (affects only QEMU, not qemu-img) + --block-drv-ro-whitelist=L + set block driver read-only whitelist + (affects only QEMU, not qemu-img) + --disable-xen disable xen backend driver support + --enable-xen enable xen backend driver support + --disable-xen-pci-passthrough + --enable-xen-pci-passthrough + --disable-brlapi disable BrlAPI + --enable-brlapi enable BrlAPI + --disable-vnc-tls disable TLS encryption for VNC server + --enable-vnc-tls enable TLS encryption for VNC server + --disable-vnc-sasl disable SASL encryption for VNC server + --enable-vnc-sasl enable SASL encryption for VNC server + --disable-vnc-jpeg disable JPEG lossy compression for VNC server + --enable-vnc-jpeg enable JPEG lossy compression for VNC server + --disable-vnc-png disable PNG compression for VNC server (default) + --enable-vnc-png enable PNG compression for VNC server + --disable-vnc-ws disable Websockets support for VNC server + --enable-vnc-ws enable Websockets support for VNC server + --disable-curses disable curses output + --enable-curses enable curses output + --disable-curl disable curl connectivity + --enable-curl enable curl connectivity + --disable-fdt disable fdt device tree + --enable-fdt enable fdt device tree + --disable-bluez disable bluez stack connectivity + --enable-bluez enable bluez stack connectivity + --disable-slirp disable SLIRP userspace network connectivity + --disable-kvm disable KVM acceleration support + --enable-kvm enable KVM acceleration support + --disable-rdma disable RDMA-based migration support + --enable-rdma enable RDMA-based migration support + --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI) + --enable-system enable all system emulation targets + --disable-system disable all system emulation targets + --enable-user enable supported user emulation targets + --disable-user disable all user emulation targets + --enable-linux-user enable all linux usermode emulation targets + --disable-linux-user disable all linux usermode emulation targets + --enable-bsd-user enable all BSD usermode emulation targets + --disable-bsd-user disable all BSD usermode emulation targets + --enable-guest-base enable GUEST_BASE support for usermode + emulation targets + --disable-guest-base disable GUEST_BASE support + --enable-pie build Position Independent Executables + --disable-pie do not build Position Independent Executables + --fmod-lib path to FMOD library + --fmod-inc path to FMOD includes + --oss-lib path to OSS library + --enable-uname-release=R Return R for uname -r in usermode emulation + --cpu=CPU Build for host CPU [$cpu] + --disable-uuid disable uuid support + --enable-uuid enable uuid support + --disable-vde disable support for vde network + --enable-vde enable support for vde network + --disable-netmap disable support for netmap network + --enable-netmap enable support for netmap network + --disable-linux-aio disable Linux AIO support + --enable-linux-aio enable Linux AIO support + --disable-cap-ng disable libcap-ng support + --enable-cap-ng enable libcap-ng support + --disable-attr disables attr and xattr support + --enable-attr enable attr and xattr support + --disable-blobs disable installing provided firmware blobs + --enable-docs enable documentation build + --disable-docs disable documentation build + --disable-vhost-net disable vhost-net acceleration support + --enable-vhost-net enable vhost-net acceleration support + --enable-trace-backend=B Set trace backend + Available backends: $($python $source_path/scripts/tracetool.py --list-backends) + --with-trace-file=NAME Full PATH,NAME of file to store traces + Default:trace-<pid> + --disable-spice disable spice + --enable-spice enable spice + --enable-rbd enable building the rados block device (rbd) + --disable-libiscsi disable iscsi support + --enable-libiscsi enable iscsi support + --disable-smartcard-nss disable smartcard nss support + --enable-smartcard-nss enable smartcard nss support + --disable-libusb disable libusb (for usb passthrough) + --enable-libusb enable libusb (for usb passthrough) + --disable-usb-redir disable usb network redirection support + --enable-usb-redir enable usb network redirection support + --disable-guest-agent disable building of the QEMU Guest Agent + --enable-guest-agent enable building of the QEMU Guest Agent + --with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent + --with-win-sdk=SDK-path path to Windows Platform SDK (to build VSS .tlb) + --disable-seccomp disable seccomp support + --enable-seccomp enables seccomp support + --with-coroutine=BACKEND coroutine backend. Supported options: + gthread, ucontext, sigaltstack, windows + --disable-coroutine-pool disable coroutine freelist (worse performance) + --enable-coroutine-pool enable coroutine freelist (better performance) + --enable-glusterfs enable GlusterFS backend + --disable-glusterfs disable GlusterFS backend + --enable-gcov enable test coverage analysis with gcov + --gcov=GCOV use specified gcov [$gcov_tool] + --enable-tpm enable TPM support + --disable-libssh2 disable ssh block device support + --enable-libssh2 enable ssh block device support + --disable-vhdx disables support for the Microsoft VHDX image format + --enable-vhdx enable support for the Microsoft VHDX image format + +NOTE: The object files are built at the place where configure is launched EOF -echo "Standard options:" -echo " --help print this message" -echo " --prefix=PREFIX install in PREFIX [$prefix]" -echo " --interp-prefix=PREFIX where to find shared libraries, etc." -echo " use %M for cpu name [$interp_prefix]" -echo " --target-list=LIST set target list (default: build everything)" -echo "Available targets: $default_target_list" | \ - fold -s -w 53 | sed -e 's/^/ /' -echo "" -echo "Advanced options (experts only):" -echo " --source-path=PATH path of source code [$source_path]" -echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]" -echo " --cc=CC use C compiler CC [$cc]" -echo " --iasl=IASL use ACPI compiler IASL [$iasl]" -echo " --host-cc=CC use C compiler CC [$host_cc] for code run at" -echo " build time" -echo " --cxx=CXX use C++ compiler CXX [$cxx]" -echo " --objcc=OBJCC use Objective-C compiler OBJCC [$objcc]" -echo " --extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS" -echo " --extra-ldflags=LDFLAGS append extra linker flags LDFLAGS" -echo " --make=MAKE use specified make [$make]" -echo " --install=INSTALL use specified install [$install]" -echo " --python=PYTHON use specified python [$python]" -echo " --smbd=SMBD use specified smbd [$smbd]" -echo " --static enable static build [$static]" -echo " --mandir=PATH install man pages in PATH" -echo " --datadir=PATH install firmware in PATH$confsuffix" -echo " --docdir=PATH install documentation in PATH$confsuffix" -echo " --bindir=PATH install binaries in PATH" -echo " --libdir=PATH install libraries in PATH" -echo " --sysconfdir=PATH install config in PATH$confsuffix" -echo " --localstatedir=PATH install local state in PATH (set at runtime on win32)" -echo " --with-confsuffix=SUFFIX suffix for QEMU data inside datadir and sysconfdir [$confsuffix]" -echo " --enable-debug-tcg enable TCG debugging" -echo " --disable-debug-tcg disable TCG debugging (default)" -echo " --enable-debug-info enable debugging information (default)" -echo " --disable-debug-info disable debugging information" -echo " --enable-debug enable common debug build options" -echo " --enable-sparse enable sparse checker" -echo " --disable-sparse disable sparse checker (default)" -echo " --disable-strip disable stripping binaries" -echo " --disable-werror disable compilation abort on warning" -echo " --disable-sdl disable SDL" -echo " --enable-sdl enable SDL" -echo " --disable-gtk disable gtk UI" -echo " --enable-gtk enable gtk UI" -echo " --disable-virtfs disable VirtFS" -echo " --enable-virtfs enable VirtFS" -echo " --disable-vnc disable VNC" -echo " --enable-vnc enable VNC" -echo " --disable-cocoa disable Cocoa (Mac OS X only)" -echo " --enable-cocoa enable Cocoa (default on Mac OS X)" -echo " --audio-drv-list=LIST set audio drivers list:" -echo " Available drivers: $audio_possible_drivers" -echo " --block-drv-whitelist=L Same as --block-drv-rw-whitelist=L" -echo " --block-drv-rw-whitelist=L" -echo " set block driver read-write whitelist" -echo " (affects only QEMU, not qemu-img)" -echo " --block-drv-ro-whitelist=L" -echo " set block driver read-only whitelist" -echo " (affects only QEMU, not qemu-img)" -echo " --disable-xen disable xen backend driver support" -echo " --enable-xen enable xen backend driver support" -echo " --disable-xen-pci-passthrough" -echo " --enable-xen-pci-passthrough" -echo " --disable-brlapi disable BrlAPI" -echo " --enable-brlapi enable BrlAPI" -echo " --disable-vnc-tls disable TLS encryption for VNC server" -echo " --enable-vnc-tls enable TLS encryption for VNC server" -echo " --disable-vnc-sasl disable SASL encryption for VNC server" -echo " --enable-vnc-sasl enable SASL encryption for VNC server" -echo " --disable-vnc-jpeg disable JPEG lossy compression for VNC server" -echo " --enable-vnc-jpeg enable JPEG lossy compression for VNC server" -echo " --disable-vnc-png disable PNG compression for VNC server (default)" -echo " --enable-vnc-png enable PNG compression for VNC server" -echo " --disable-vnc-ws disable Websockets support for VNC server" -echo " --enable-vnc-ws enable Websockets support for VNC server" -echo " --disable-curses disable curses output" -echo " --enable-curses enable curses output" -echo " --disable-curl disable curl connectivity" -echo " --enable-curl enable curl connectivity" -echo " --disable-fdt disable fdt device tree" -echo " --enable-fdt enable fdt device tree" -echo " --disable-bluez disable bluez stack connectivity" -echo " --enable-bluez enable bluez stack connectivity" -echo " --disable-slirp disable SLIRP userspace network connectivity" -echo " --disable-kvm disable KVM acceleration support" -echo " --enable-kvm enable KVM acceleration support" -echo " --disable-rdma disable RDMA-based migration support" -echo " --enable-rdma enable RDMA-based migration support" -echo " --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)" -echo " --enable-system enable all system emulation targets" -echo " --disable-system disable all system emulation targets" -echo " --enable-user enable supported user emulation targets" -echo " --disable-user disable all user emulation targets" -echo " --enable-linux-user enable all linux usermode emulation targets" -echo " --disable-linux-user disable all linux usermode emulation targets" -echo " --enable-bsd-user enable all BSD usermode emulation targets" -echo " --disable-bsd-user disable all BSD usermode emulation targets" -echo " --enable-guest-base enable GUEST_BASE support for usermode" -echo " emulation targets" -echo " --disable-guest-base disable GUEST_BASE support" -echo " --enable-pie build Position Independent Executables" -echo " --disable-pie do not build Position Independent Executables" -echo " --fmod-lib path to FMOD library" -echo " --fmod-inc path to FMOD includes" -echo " --oss-lib path to OSS library" -echo " --enable-uname-release=R Return R for uname -r in usermode emulation" -echo " --cpu=CPU Build for host CPU [$cpu]" -echo " --disable-uuid disable uuid support" -echo " --enable-uuid enable uuid support" -echo " --disable-vde disable support for vde network" -echo " --enable-vde enable support for vde network" -echo " --disable-netmap disable support for netmap network" -echo " --enable-netmap enable support for netmap network" -echo " --disable-linux-aio disable Linux AIO support" -echo " --enable-linux-aio enable Linux AIO support" -echo " --disable-cap-ng disable libcap-ng support" -echo " --enable-cap-ng enable libcap-ng support" -echo " --disable-attr disables attr and xattr support" -echo " --enable-attr enable attr and xattr support" -echo " --disable-blobs disable installing provided firmware blobs" -echo " --enable-docs enable documentation build" -echo " --disable-docs disable documentation build" -echo " --disable-vhost-net disable vhost-net acceleration support" -echo " --enable-vhost-net enable vhost-net acceleration support" -echo " --enable-trace-backend=B Set trace backend" -echo " Available backends:" $($python "$source_path"/scripts/tracetool.py --list-backends) -echo " --with-trace-file=NAME Full PATH,NAME of file to store traces" -echo " Default:trace-<pid>" -echo " --disable-spice disable spice" -echo " --enable-spice enable spice" -echo " --enable-rbd enable building the rados block device (rbd)" -echo " --disable-libiscsi disable iscsi support" -echo " --enable-libiscsi enable iscsi support" -echo " --disable-smartcard-nss disable smartcard nss support" -echo " --enable-smartcard-nss enable smartcard nss support" -echo " --disable-libusb disable libusb (for usb passthrough)" -echo " --enable-libusb enable libusb (for usb passthrough)" -echo " --disable-usb-redir disable usb network redirection support" -echo " --enable-usb-redir enable usb network redirection support" -echo " --disable-guest-agent disable building of the QEMU Guest Agent" -echo " --enable-guest-agent enable building of the QEMU Guest Agent" -echo " --with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent" -echo " --with-win-sdk=SDK-path path to Windows Platform SDK (to build VSS .tlb)" -echo " --disable-seccomp disable seccomp support" -echo " --enable-seccomp enables seccomp support" -echo " --with-coroutine=BACKEND coroutine backend. Supported options:" -echo " gthread, ucontext, sigaltstack, windows" -echo " --disable-coroutine-pool disable coroutine freelist (worse performance)" -echo " --enable-coroutine-pool enable coroutine freelist (better performance)" -echo " --enable-glusterfs enable GlusterFS backend" -echo " --disable-glusterfs disable GlusterFS backend" -echo " --enable-gcov enable test coverage analysis with gcov" -echo " --gcov=GCOV use specified gcov [$gcov_tool]" -echo " --enable-tpm enable TPM support" -echo " --disable-libssh2 disable ssh block device support" -echo " --enable-libssh2 enable ssh block device support" -echo " --disable-vhdx disables support for the Microsoft VHDX image format" -echo " --enable-vhdx enable support for the Microsoft VHDX image format" -echo "" -echo "NOTE: The object files are built at the place where configure is launched" exit 1 fi @@ -1419,25 +1438,6 @@ if test "$solaris" = "yes" ; then fi fi -if ! has $python; then - error_exit "Python not found. Use --python=/path/to/python" -fi - -# Note that if the Python conditional here evaluates True we will exit -# with status 1 which is a shell 'false' value. -if ! $python -c 'import sys; sys.exit(sys.version_info < (2,4) or sys.version_info >= (3,))'; then - error_exit "Cannot use '$python', Python 2.4 or later is required." \ - "Note that Python 3 or later is not yet supported." \ - "Use --python=/path/to/python to specify a supported Python." -fi - -# The -B switch was added in Python 2.6. -# If it is supplied, compiled files are not written. -# Use it for Python versions which support it. -if $python -B -c 'import sys; sys.exit(0)' 2>/dev/null; then - python="$python -B" -fi - if test -z "${target_list+xxx}" ; then target_list="$default_target_list" else diff --git a/cpu-exec.c b/cpu-exec.c index 30cfa2a63a..3c4800fc1f 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -53,7 +53,25 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc) static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) { CPUArchState *env = cpu->env_ptr; - uintptr_t next_tb = tcg_qemu_tb_exec(env, tb_ptr); + uintptr_t next_tb; + +#if defined(DEBUG_DISAS) + if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { +#if defined(TARGET_I386) + log_cpu_state(cpu, CPU_DUMP_CCOP); +#elif defined(TARGET_M68K) + /* ??? Should not modify env state for dumping. */ + cpu_m68k_flush_flags(env, env->cc_op); + env->cc_op = CC_OP_FLAGS; + env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4); + log_cpu_state(cpu, 0); +#else + log_cpu_state(cpu, 0); +#endif + } +#endif /* DEBUG_DISAS */ + + next_tb = tcg_qemu_tb_exec(env, tb_ptr); if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) { /* We didn't start executing this TB (eg because the instruction * counter hit zero); we must restore the guest PC to the address @@ -579,22 +597,6 @@ int cpu_exec(CPUArchState *env) env->exception_index = EXCP_INTERRUPT; cpu_loop_exit(env); } -#if defined(DEBUG_DISAS) - if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { - /* restore flags in standard format */ -#if defined(TARGET_I386) - log_cpu_state(cpu, CPU_DUMP_CCOP); -#elif defined(TARGET_M68K) - cpu_m68k_flush_flags(env, env->cc_op); - env->cc_op = CC_OP_FLAGS; - env->sr = (env->sr & 0xffe0) - | env->cc_dest | (env->cc_x << 4); - log_cpu_state(cpu, 0); -#else - log_cpu_state(cpu, 0); -#endif - } -#endif /* DEBUG_DISAS */ spin_lock(&tcg_ctx.tb_ctx.tb_lock); tb = tb_find_fast(env); /* Note: we do it here to avoid a gcc bug on Mac OS X when diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 93849c8d36..9e8a89c233 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -544,9 +544,13 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data) k->revision = 0x03; k->class_id = PCI_CLASS_BRIDGE_OTHER; dc->desc = "PM"; - dc->no_user = 1; dc->vmsd = &vmstate_acpi; dc->props = piix4_pm_properties; + /* + * Reason: part of PIIX4 southbridge, needs to be wired up, + * e.g. by mips_malta_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo piix4_pm_info = { diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index 59e1bb8388..71a5a37fdc 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -934,11 +934,9 @@ static int typhoon_pcihost_init(SysBusDevice *dev) static void typhoon_pcihost_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = typhoon_pcihost_init; - dc->no_user = 1; } static const TypeInfo typhoon_pcihost_info = { diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index c75b425c01..d76a1d1f78 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -126,7 +126,7 @@ typedef struct { SysBusDevice parent_obj; /*< public >*/ - MemoryRegion *iomem; + MemoryRegion iomem; uint32_t regs[NUM_REGS]; } HighbankRegsState; @@ -155,10 +155,9 @@ static int highbank_regs_init(SysBusDevice *dev) { HighbankRegsState *s = HIGHBANK_REGISTERS(dev); - s->iomem = g_new(MemoryRegion, 1); - memory_region_init_io(s->iomem, OBJECT(s), &hb_mem_ops, s->regs, + memory_region_init_io(&s->iomem, OBJECT(s), &hb_mem_ops, s->regs, "highbank_regs", 0x1000); - sysbus_init_mmio(dev, s->iomem); + sysbus_init_mmio(dev, &s->iomem); return 0; } diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c index 9402c841e9..d8e075e26d 100644 --- a/hw/arm/mainstone.c +++ b/hw/arm/mainstone.c @@ -45,7 +45,7 @@ #define S1_STSCHG_IRQ 14 #define S1_IRQ 15 -static struct keymap map[0xE0] = { +static const struct keymap map[0xE0] = { [0 ... 0xDF] = { -1, -1 }, [0x1e] = {0,0}, /* a */ [0x30] = {0,1}, /* b */ @@ -75,9 +75,18 @@ static struct keymap map[0xE0] = { [0x2c] = {4,3}, /* z */ [0xc7] = {5,0}, /* Home */ [0x2a] = {5,1}, /* shift */ - [0x39] = {5,2}, /* space */ + /* + * There are two matrix positions which map to space, + * but QEMU can only use one of them for the reverse + * mapping, so simply use the second one. + */ + /* [0x39] = {5,2}, space */ [0x39] = {5,3}, /* space */ - [0x1c] = {5,5}, /* enter */ + /* + * Matrix position {5,4} and other keys are missing here. + * TODO: Compare with Linux code and test real hardware. + */ + [0x1c] = {5,5}, /* enter (TODO: might be wrong) */ [0xc8] = {6,0}, /* up */ [0xd0] = {6,1}, /* down */ [0xcb] = {6,2}, /* left */ diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index f7e8b7e8fa..aef2bde0c4 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -390,7 +390,6 @@ static void vpb_sic_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = vpb_sic_init; - dc->no_user = 1; dc->vmsd = &vmstate_vpb_sic; } diff --git a/hw/arm/z2.c b/hw/arm/z2.c index d52c5019b3..97367b1f8b 100644 --- a/hw/arm/z2.c +++ b/hw/arm/z2.c @@ -33,7 +33,7 @@ #define DPRINTF(fmt, ...) #endif -static struct keymap map[0x100] = { +static const struct keymap map[0x100] = { [0 ... 0xff] = { -1, -1 }, [0x3b] = {0, 0}, /* Option = F1 */ [0xc8] = {0, 1}, /* Up */ diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index 6ab8c245d3..d41f82cec4 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -900,7 +900,7 @@ static const IntelHDAReg *intel_hda_reg_find(IntelHDAState *d, hwaddr addr) { const IntelHDAReg *reg; - if (addr >= sizeof(regtab)/sizeof(regtab[0])) { + if (addr >= ARRAY_SIZE(regtab)) { goto noreg; } reg = regtab+addr; @@ -1025,7 +1025,7 @@ static void intel_hda_regs_reset(IntelHDAState *d) uint32_t *addr; int i; - for (i = 0; i < sizeof(regtab)/sizeof(regtab[0]); i++) { + for (i = 0; i < ARRAY_SIZE(regtab); i++) { if (regtab[i].name == NULL) { continue; } diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c index 97194ce7ad..cdce238f55 100644 --- a/hw/audio/marvell_88w8618.c +++ b/hw/audio/marvell_88w8618.c @@ -288,6 +288,8 @@ static void mv88w8618_audio_class_init(ObjectClass *klass, void *data) dc->reset = mv88w8618_audio_reset; dc->vmsd = &mv88w8618_audio_vmsd; dc->props = mv88w8618_audio_properties; + /* Reason: pointer property "wm8750" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo mv88w8618_audio_info = { diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index 9004ce3d1f..f980d66b2f 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -192,8 +192,9 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data) dc->realize = pcspk_realizefn; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); - dc->no_user = 1; dc->props = pcspk_properties; + /* Reason: pointer property "pit", realize sets global pcspk_state */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo pcspk_info = { diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c index 5393b520b7..ed82be54e8 100644 --- a/hw/audio/pl041.c +++ b/hw/audio/pl041.c @@ -632,7 +632,6 @@ static void pl041_device_class_init(ObjectClass *klass, void *data) k->init = pl041_init; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); - dc->no_user = 1; dc->reset = pl041_device_reset; dc->vmsd = &vmstate_pl041; dc->props = pl041_device_properties; diff --git a/hw/block/fdc.c b/hw/block/fdc.c index c5a6c21215..592b58f9b5 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -2234,7 +2234,6 @@ static void isabus_fdc_class_init(ObjectClass *klass, void *data) dc->realize = isabus_fdc_realize; dc->fw_name = "fdc"; - dc->no_user = 1; dc->reset = fdctrl_external_reset_isa; dc->vmsd = &vmstate_isa_fdc; dc->props = isa_fdc_properties; diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index eef23a0ccc..19b59ccddb 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -192,10 +192,9 @@ typedef struct Exynos4210UartState { static const char *exynos4210_uart_regname(hwaddr offset) { - int regs_number = sizeof(exynos4210_uart_regs) / sizeof(Exynos4210UartReg); int i; - for (i = 0; i < regs_number; i++) { + for (i = 0; i < ARRAY_SIZE(exynos4210_uart_regs); i++) { if (offset == exynos4210_uart_regs[i].offset) { return exynos4210_uart_regs[i].name; } @@ -544,10 +543,9 @@ static void exynos4210_uart_event(void *opaque, int event) static void exynos4210_uart_reset(DeviceState *dev) { Exynos4210UartState *s = EXYNOS4210_UART(dev); - int regs_number = sizeof(exynos4210_uart_regs)/sizeof(Exynos4210UartReg); int i; - for (i = 0; i < regs_number; i++) { + for (i = 0; i < ARRAY_SIZE(exynos4210_uart_regs); i++) { s->reg[I_(exynos4210_uart_regs[i].offset)] = exynos4210_uart_regs[i].reset_value; } diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e374a9399f..bbd780aad1 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -481,11 +481,6 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam return bus; } -void qbus_free(BusState *bus) -{ - object_unparent(OBJECT(bus)); -} - static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev) { BusClass *bc = BUS_GET_CLASS(bus); @@ -794,7 +789,7 @@ static void device_unparent(Object *obj) while (dev->num_child_bus) { bus = QLIST_FIRST(&dev->child_bus); - qbus_free(bus); + object_unparent(OBJECT(bus)); } if (dev->realized) { object_property_set_bool(obj, false, "realized", NULL); diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 146f50aa15..f4e760d6eb 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -257,6 +257,13 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data) DeviceClass *k = DEVICE_CLASS(klass); k->init = sysbus_device_init; k->bus_type = TYPE_SYSTEM_BUS; + /* + * device_add plugs devices into suitable bus. For "real" buses, + * that actually connects the device. For sysbus, the connections + * need to be made separately, and device_add can't do that. The + * device would be left unconnected, and could not possibly work. + */ + k->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo sysbus_device_type_info = { diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c index 9a4ea7e2df..7f44c59b25 100644 --- a/hw/cpu/icc_bus.c +++ b/hw/cpu/icc_bus.c @@ -43,15 +43,13 @@ static const TypeInfo icc_bus_info = { static void icc_device_realize(DeviceState *dev, Error **errp) { - ICCDevice *id = ICC_DEVICE(dev); - ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(id); - - if (idc->init) { - if (idc->init(id) < 0) { - error_setg(errp, "%s initialization failed.", - object_get_typename(OBJECT(dev))); - } + ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev); + + /* convert to QOM */ + if (idc->realize) { + idc->realize(dev, errp); } + } static void icc_device_class_init(ObjectClass *oc, void *data) diff --git a/hw/display/pl110.c b/hw/display/pl110.c index 790e5108ed..ab689e9aae 100644 --- a/hw/display/pl110.c +++ b/hw/display/pl110.c @@ -496,7 +496,6 @@ static void pl110_class_init(ObjectClass *klass, void *data) k->init = pl110_initfn; set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); - dc->no_user = 1; dc->vmsd = &vmstate_pl110; } diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 35b90155a2..cb7bda9803 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -381,7 +381,6 @@ static void pl080_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); - dc->no_user = 1; dc->vmsd = &vmstate_pl080; } diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c index 2a92ffb82e..eac338f1bc 100644 --- a/hw/dma/sparc32_dma.c +++ b/hw/dma/sparc32_dma.c @@ -304,6 +304,8 @@ static void sparc32_dma_class_init(ObjectClass *klass, void *data) dc->reset = dma_reset; dc->vmsd = &vmstate_dma; dc->props = sparc32_dma_properties; + /* Reason: pointer property "iommu_opaque" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo sparc32_dma_info = { diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c index b8f572bb70..938782a45d 100644 --- a/hw/gpio/omap_gpio.c +++ b/hw/gpio/omap_gpio.c @@ -759,6 +759,8 @@ static void omap_gpio_class_init(ObjectClass *klass, void *data) k->init = omap_gpio_init; dc->reset = omap_gpif_reset; dc->props = omap_gpio_properties; + /* Reason: pointer property "clk" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap_gpio_info = { @@ -788,6 +790,8 @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data) k->init = omap2_gpio_init; dc->reset = omap2_gpif_reset; dc->props = omap2_gpio_properties; + /* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap2_gpio_info = { diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c index f528b2b38e..2d8e2b7839 100644 --- a/hw/i2c/omap_i2c.c +++ b/hw/i2c/omap_i2c.c @@ -475,6 +475,8 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data) k->init = omap_i2c_init; dc->props = omap_i2c_properties; dc->reset = omap_i2c_reset; + /* Reason: pointer properties "iclk", "fclk" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap_i2c_info = { diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c index 0154283762..0218f8a0eb 100644 --- a/hw/i2c/smbus_eeprom.c +++ b/hw/i2c/smbus_eeprom.c @@ -121,6 +121,8 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data) sc->write_data = eeprom_write_data; sc->read_data = eeprom_read_data; dc->props = smbus_eeprom_properties; + /* Reason: pointer property "data" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo smbus_eeprom_info = { diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c index ca229789f4..8d47eaffc8 100644 --- a/hw/i2c/smbus_ich9.c +++ b/hw/i2c/smbus_ich9.c @@ -97,11 +97,15 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_ICH9_6; k->revision = ICH9_A2_SMB_REVISION; k->class_id = PCI_CLASS_SERIAL_SMBUS; - dc->no_user = 1; dc->vmsd = &vmstate_ich9_smbus; dc->desc = "ICH9 SMBUS Bridge"; k->init = ich9_smbus_initfn; k->config_write = ich9_smbus_write_config; + /* + * Reason: part of ICH9 southbridge, needs to be wired up by + * pc_q35_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base) diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c index 5609063120..e873b509a5 100644 --- a/hw/i386/kvm/apic.c +++ b/hw/i386/kvm/apic.c @@ -25,9 +25,9 @@ static inline uint32_t kvm_apic_get_reg(struct kvm_lapic_state *kapic, return *((uint32_t *)(kapic->regs + (reg_id << 4))); } -void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) +void kvm_put_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); int i; memset(kapic, 0, sizeof(*kapic)); @@ -51,9 +51,9 @@ void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) kvm_apic_set_reg(kapic, 0x3e, s->divide_conf); } -void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) +void kvm_get_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); int i, v; s->id = kvm_apic_get_reg(kapic, 0x2) >> 24; @@ -171,8 +171,10 @@ static const MemoryRegionOps kvm_apic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void kvm_apic_init(APICCommonState *s) +static void kvm_apic_realize(DeviceState *dev, Error **errp) { + APICCommonState *s = APIC_COMMON(dev); + memory_region_init_io(&s->io_memory, NULL, &kvm_apic_io_ops, s, "kvm-apic-msi", APIC_SPACE_SIZE); @@ -185,7 +187,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); - k->init = kvm_apic_init; + k->realize = kvm_apic_realize; k->set_base = kvm_apic_set_base; k->set_tpr = kvm_apic_set_tpr; k->get_tpr = kvm_apic_get_tpr; diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 383938d1bc..892aa025f4 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -114,7 +114,6 @@ static void kvmclock_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = kvmclock_realize; - dc->no_user = 1; dc->vmsd = &kvmclock_vmsd; } diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c index f11a540825..d2a6c4cf60 100644 --- a/hw/i386/kvm/ioapic.c +++ b/hw/i386/kvm/ioapic.c @@ -127,11 +127,13 @@ static void kvm_ioapic_set_irq(void *opaque, int irq, int level) apic_report_irq_delivered(delivered); } -static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no) +static void kvm_ioapic_realize(DeviceState *dev, Error **errp) { + IOAPICCommonState *s = IOAPIC_COMMON(dev); + memory_region_init_reservation(&s->io_memory, NULL, "kvm-ioapic", 0x1000); - qdev_init_gpio_in(DEVICE(s), kvm_ioapic_set_irq, IOAPIC_NUM_PINS); + qdev_init_gpio_in(dev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS); } static Property kvm_ioapic_properties[] = { @@ -144,7 +146,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data) IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - k->init = kvm_ioapic_init; + k->realize = kvm_ioapic_realize; k->pre_save = kvm_ioapic_get; k->post_load = kvm_ioapic_put; dc->reset = kvm_ioapic_reset; diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 2d876009fc..44ee62a233 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -827,7 +827,6 @@ static void vapic_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->no_user = 1; dc->reset = vapic_reset; dc->vmsd = &vmstate_vapic; dc->realize = vapic_realize; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3cd8f383f3..e9831ca411 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -547,10 +547,15 @@ static void port92_class_initfn(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->no_user = 1; dc->realize = port92_realizefn; dc->reset = port92_reset; dc->vmsd = &vmstate_port92_isa; + /* + * Reason: unlike ordinary ISA devices, this one needs additional + * wiring: its A20 output line needs to be wired up by + * port92_init(). + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo port92_info = { diff --git a/hw/ide/piix.c b/hw/ide/piix.c index ab36749417..9b5960b44e 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -248,7 +248,6 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->no_user = 1; } static const TypeInfo piix3_ide_info = { @@ -267,7 +266,6 @@ static void piix3_ide_xen_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->no_user = 1; dc->unplug = pci_piix3_xen_ide_unplug; } @@ -289,7 +287,6 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371AB; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->no_user = 1; } static const TypeInfo piix4_ide_info = { diff --git a/hw/ide/via.c b/hw/ide/via.c index 99468c773e..198123b026 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -225,7 +225,6 @@ static void via_ide_class_init(ObjectClass *klass, void *data) k->revision = 0x06; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->no_user = 1; } static const TypeInfo via_ide_info = { diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index ce86237cf3..655b8c5011 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -522,7 +522,6 @@ static void i8042_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = i8042_realizefn; - dc->no_user = 1; dc->vmsd = &vmstate_kbd_isa; } diff --git a/hw/input/pxa2xx_keypad.c b/hw/input/pxa2xx_keypad.c index 846d1370de..b90b0ba102 100644 --- a/hw/input/pxa2xx_keypad.c +++ b/hw/input/pxa2xx_keypad.c @@ -85,7 +85,7 @@ struct PXA2xxKeyPadState { MemoryRegion iomem; qemu_irq irq; - struct keymap *map; + const struct keymap *map; int pressed_cnt; int alt_code; @@ -322,8 +322,8 @@ PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem, return s; } -void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map, - int size) +void pxa27x_register_keypad(PXA2xxKeyPadState *kp, + const struct keymap *map, int size) { if(!map || size < 0x80) { fprintf(stderr, "%s - No PXA keypad map defined\n", __FUNCTION__); diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c index abd032b794..6a5053352a 100644 --- a/hw/input/vmmouse.c +++ b/hw/input/vmmouse.c @@ -282,10 +282,11 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = vmmouse_realizefn; - dc->no_user = 1; dc->reset = vmmouse_reset; dc->vmsd = &vmstate_vmmouse; dc->props = vmmouse_properties; + /* Reason: pointer property "ps2_mouse" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo vmmouse_info = { diff --git a/hw/intc/apic.c b/hw/intc/apic.c index a913186ed0..3d3deb6298 100644 --- a/hw/intc/apic.c +++ b/hw/intc/apic.c @@ -171,9 +171,9 @@ static void apic_local_deliver(APICCommonState *s, int vector) } } -void apic_deliver_pic_intr(DeviceState *d, int level) +void apic_deliver_pic_intr(DeviceState *dev, int level) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); if (level) { apic_local_deliver(s, APIC_LVT_LINT0); @@ -376,9 +376,9 @@ static void apic_update_irq(APICCommonState *s) } } -void apic_poll_irq(DeviceState *d) +void apic_poll_irq(DeviceState *dev) { - APICCommonState *s = APIC_COMMON(d); + APICCommonState *s = APIC_COMMON(dev); apic_sync_vapic(s, SYNC_FROM_VAPIC); apic_update_irq(s); @@ -482,9 +482,9 @@ static void apic_startup(APICCommonState *s, int vector_num) cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI); } -void apic_sipi(DeviceState *d) +void apic_sipi(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI); @@ -494,11 +494,11 @@ void apic_sipi(DeviceState *d) s->wait_for_sipi = 0; } -static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode, +static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); uint32_t deliver_bitmask[MAX_APIC_WORDS]; int dest_shorthand = (s->icr[0] >> 18) & 3; APICCommonState *apic_iter; @@ -551,9 +551,9 @@ static bool apic_check_pic(APICCommonState *s) return true; } -int apic_get_interrupt(DeviceState *d) +int apic_get_interrupt(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); int intno; /* if the APIC is installed or enabled, we let the 8259 handle the @@ -585,9 +585,9 @@ int apic_get_interrupt(DeviceState *d) return intno; } -int apic_accept_pic_intr(DeviceState *d) +int apic_accept_pic_intr(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); uint32_t lvt0; if (!s) @@ -657,16 +657,16 @@ static void apic_mem_writew(void *opaque, hwaddr addr, uint32_t val) static uint32_t apic_mem_readl(void *opaque, hwaddr addr) { - DeviceState *d; + DeviceState *dev; APICCommonState *s; uint32_t val; int index; - d = cpu_get_current_apic(); - if (!d) { + dev = cpu_get_current_apic(); + if (!dev) { return 0; } - s = DO_UPCAST(APICCommonState, busdev.qdev, d); + s = APIC_COMMON(dev); index = (addr >> 4) & 0xff; switch(index) { @@ -752,7 +752,7 @@ static void apic_send_msi(hwaddr addr, uint32_t data) static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val) { - DeviceState *d; + DeviceState *dev; APICCommonState *s; int index = (addr >> 4) & 0xff; if (addr > 0xfff || !index) { @@ -765,11 +765,11 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val) return; } - d = cpu_get_current_apic(); - if (!d) { + dev = cpu_get_current_apic(); + if (!dev) { return; } - s = DO_UPCAST(APICCommonState, busdev.qdev, d); + s = APIC_COMMON(dev); trace_apic_mem_writel(addr, val); @@ -810,7 +810,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val) break; case 0x30: s->icr[0] = val; - apic_deliver(d, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, + apic_deliver(dev, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff), (s->icr[0] >> 15) & 1); break; @@ -871,8 +871,10 @@ static const MemoryRegionOps apic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void apic_init(APICCommonState *s) +static void apic_realize(DeviceState *dev, Error **errp) { + APICCommonState *s = APIC_COMMON(dev); + memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi", APIC_SPACE_SIZE); @@ -886,7 +888,7 @@ static void apic_class_init(ObjectClass *klass, void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); - k->init = apic_init; + k->realize = apic_realize; k->set_base = apic_set_base; k->set_tpr = apic_set_tpr; k->get_tpr = apic_get_tpr; diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index a0beb10863..c623fcc6d8 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -27,21 +27,21 @@ static int apic_irq_delivered; bool apic_report_tpr_access; -void cpu_set_apic_base(DeviceState *d, uint64_t val) +void cpu_set_apic_base(DeviceState *dev, uint64_t val) { trace_cpu_set_apic_base(val); - if (d) { - APICCommonState *s = APIC_COMMON(d); + if (dev) { + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); info->set_base(s, val); } } -uint64_t cpu_get_apic_base(DeviceState *d) +uint64_t cpu_get_apic_base(DeviceState *dev) { - if (d) { - APICCommonState *s = APIC_COMMON(d); + if (dev) { + APICCommonState *s = APIC_COMMON(dev); trace_cpu_get_apic_base((uint64_t)s->apicbase); return s->apicbase; } else { @@ -50,39 +50,39 @@ uint64_t cpu_get_apic_base(DeviceState *d) } } -void cpu_set_apic_tpr(DeviceState *d, uint8_t val) +void cpu_set_apic_tpr(DeviceState *dev, uint8_t val) { APICCommonState *s; APICCommonClass *info; - if (!d) { + if (!dev) { return; } - s = APIC_COMMON(d); + s = APIC_COMMON(dev); info = APIC_COMMON_GET_CLASS(s); info->set_tpr(s, val); } -uint8_t cpu_get_apic_tpr(DeviceState *d) +uint8_t cpu_get_apic_tpr(DeviceState *dev) { APICCommonState *s; APICCommonClass *info; - if (!d) { + if (!dev) { return 0; } - s = APIC_COMMON(d); + s = APIC_COMMON(dev); info = APIC_COMMON_GET_CLASS(s); return info->get_tpr(s); } -void apic_enable_tpr_access_reporting(DeviceState *d, bool enable) +void apic_enable_tpr_access_reporting(DeviceState *dev, bool enable) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); apic_report_tpr_access = enable; @@ -91,19 +91,19 @@ void apic_enable_tpr_access_reporting(DeviceState *d, bool enable) } } -void apic_enable_vapic(DeviceState *d, hwaddr paddr) +void apic_enable_vapic(DeviceState *dev, hwaddr paddr) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); s->vapic_paddr = paddr; info->vapic_base_update(s); } -void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip, +void apic_handle_tpr_access_report(DeviceState *dev, target_ulong ip, TPRAccess access) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access); } @@ -129,9 +129,9 @@ int apic_get_irq_delivered(void) return apic_irq_delivered; } -void apic_deliver_nmi(DeviceState *d) +void apic_deliver_nmi(DeviceState *dev) { - APICCommonState *s = APIC_COMMON(d); + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); info->external_nmi(s); @@ -170,9 +170,9 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time) return true; } -void apic_init_reset(DeviceState *d) +void apic_init_reset(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); int i; if (!s) { @@ -203,19 +203,19 @@ void apic_init_reset(DeviceState *d) s->timer_expiry = -1; } -void apic_designate_bsp(DeviceState *d) +void apic_designate_bsp(DeviceState *dev) { - if (d == NULL) { + if (dev == NULL) { return; } - APICCommonState *s = APIC_COMMON(d); + APICCommonState *s = APIC_COMMON(dev); s->apicbase |= MSR_IA32_APICBASE_BSP; } -static void apic_reset_common(DeviceState *d) +static void apic_reset_common(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); bool bsp; @@ -226,7 +226,7 @@ static void apic_reset_common(DeviceState *d) s->vapic_paddr = 0; info->vapic_base_update(s); - apic_init_reset(d); + apic_init_reset(dev); if (bsp) { /* @@ -284,7 +284,7 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id) return 0; } -static int apic_init_common(ICCDevice *dev) +static void apic_common_realize(DeviceState *dev, Error **errp) { APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info; @@ -293,14 +293,16 @@ static int apic_init_common(ICCDevice *dev) static bool mmio_registered; if (apic_no >= MAX_APICS) { - return -1; + error_setg(errp, "%s initialization failed.", + object_get_typename(OBJECT(dev))); + return; } s->idx = apic_no++; info = APIC_COMMON_GET_CLASS(s); - info->init(s); + info->realize(dev, errp); if (!mmio_registered) { - ICCBus *b = ICC_BUS(qdev_get_parent_bus(DEVICE(dev))); + ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); mmio_registered = true; } @@ -315,7 +317,6 @@ static int apic_init_common(ICCDevice *dev) info->enable_tpr_reporting(s, true); } - return 0; } static void apic_dispatch_pre_save(void *opaque) @@ -386,9 +387,13 @@ static void apic_common_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_apic_common; dc->reset = apic_reset_common; - dc->no_user = 1; dc->props = apic_properties_common; - idc->init = apic_init_common; + idc->realize = apic_common_realize; + /* + * Reason: APIC and CPU need to be wired up by + * x86_cpu_apic_create() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo apic_common_type = { @@ -400,9 +405,9 @@ static const TypeInfo apic_common_type = { .abstract = true, }; -static void register_types(void) +static void apic_common_register_types(void) { type_register_static(&apic_common_type); } -type_init(register_types) +type_init(apic_common_register_types) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 6c5965093e..9409684ce8 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -709,7 +709,6 @@ static void arm_gic_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); ARMGICClass *agc = ARM_GIC_CLASS(klass); - dc->no_user = 1; agc->parent_realize = dc->realize; dc->realize = arm_gic_realize; } diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index 710607b044..e4fc65028a 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -156,7 +156,6 @@ static void arm_gic_common_class_init(ObjectClass *klass, void *data) dc->realize = arm_gic_common_realize; dc->props = arm_gic_common_properties; dc->vmsd = &vmstate_gic; - dc->no_user = 1; } static const TypeInfo arm_gic_common_type = { diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index f71397542a..59a3da5a6b 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -150,7 +150,6 @@ static void kvm_arm_gic_class_init(ObjectClass *klass, void *data) kgc->parent_reset = dc->reset; dc->realize = kvm_arm_gic_realize; dc->reset = kvm_arm_gic_reset; - dc->no_user = 1; } static const TypeInfo kvm_arm_gic_info = { diff --git a/hw/intc/etraxfs_pic.c b/hw/intc/etraxfs_pic.c index e02da533cb..636262b49f 100644 --- a/hw/intc/etraxfs_pic.c +++ b/hw/intc/etraxfs_pic.c @@ -170,6 +170,10 @@ static void etraxfs_pic_class_init(ObjectClass *klass, void *data) k->init = etraxfs_pic_init; dc->props = etraxfs_pic_properties; + /* + * Note: pointer property "interrupt_vector" may remain null, thus + * no need for dc->cannot_instantiate_with_device_add_yet = true; + */ } static const TypeInfo etraxfs_pic_info = { diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c index 42e00bc4b8..d1813f76b6 100644 --- a/hw/intc/grlib_irqmp.c +++ b/hw/intc/grlib_irqmp.c @@ -355,6 +355,8 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data) k->init = grlib_irqmp_init; dc->reset = grlib_irqmp_reset; dc->props = grlib_irqmp_properties; + /* Reason: pointer properties "set_pil_in", "set_pil_in_opaque" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo grlib_irqmp_info = { diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c index 803d037f68..9d293999be 100644 --- a/hw/intc/i8259_common.c +++ b/hw/intc/i8259_common.c @@ -135,9 +135,15 @@ static void pic_common_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->vmsd = &vmstate_pic_common; - dc->no_user = 1; dc->props = pic_properties_common; dc->realize = pic_common_realize; + /* + * Reason: unlike ordinary ISA devices, the PICs need additional + * wiring: its IRQ input lines are set up by board code, and the + * wiring of the slave to the master is hard-coded in device model + * code. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo pic_common_type = { diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c index d866e00297..652dd47a1c 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c @@ -36,6 +36,9 @@ static IOAPICCommonState *ioapics[MAX_IOAPICS]; +/* global variable from ioapic_common.c */ +extern int ioapic_no; + static void ioapic_service(IOAPICCommonState *s) { uint8_t i; @@ -225,14 +228,16 @@ static const MemoryRegionOps ioapic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void ioapic_init(IOAPICCommonState *s, int instance_no) +static void ioapic_realize(DeviceState *dev, Error **errp) { + IOAPICCommonState *s = IOAPIC_COMMON(dev); + memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s, "ioapic", 0x1000); - qdev_init_gpio_in(DEVICE(s), ioapic_set_irq, IOAPIC_NUM_PINS); + qdev_init_gpio_in(dev, ioapic_set_irq, IOAPIC_NUM_PINS); - ioapics[instance_no] = s; + ioapics[ioapic_no] = s; } static void ioapic_class_init(ObjectClass *klass, void *data) @@ -240,7 +245,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data) IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - k->init = ioapic_init; + k->realize = ioapic_realize; dc->reset = ioapic_reset_common; } diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c index 6b705c1546..4d3d309b62 100644 --- a/hw/intc/ioapic_common.c +++ b/hw/intc/ioapic_common.c @@ -23,6 +23,14 @@ #include "hw/i386/ioapic_internal.h" #include "hw/sysbus.h" +/* ioapic_no count start from 0 to MAX_IOAPICS, + * remove as static variable from ioapic_common_init. + * now as a global variable, let child to increase the counter + * then we can drop the 'instance_no' argument + * and convert to our QOM's realize function + */ +int ioapic_no; + void ioapic_reset_common(DeviceState *dev) { IOAPICCommonState *s = IOAPIC_COMMON(dev); @@ -61,7 +69,6 @@ static void ioapic_common_realize(DeviceState *dev, Error **errp) { IOAPICCommonState *s = IOAPIC_COMMON(dev); IOAPICCommonClass *info; - static int ioapic_no; if (ioapic_no >= MAX_IOAPICS) { error_setg(errp, "Only %d ioapics allowed", MAX_IOAPICS); @@ -69,7 +76,7 @@ static void ioapic_common_realize(DeviceState *dev, Error **errp) } info = IOAPIC_COMMON_GET_CLASS(s); - info->init(s, ioapic_no); + info->realize(dev, errp); sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io_memory); ioapic_no++; @@ -98,7 +105,6 @@ static void ioapic_common_class_init(ObjectClass *klass, void *data) dc->realize = ioapic_common_realize; dc->vmsd = &vmstate_ioapic_common; - dc->no_user = 1; } static const TypeInfo ioapic_common_type = { @@ -110,9 +116,9 @@ static const TypeInfo ioapic_common_type = { .abstract = true, }; -static void register_types(void) +static void ioapic_common_register_types(void) { type_register_static(&ioapic_common_type); } -type_init(register_types) +type_init(ioapic_common_register_types) diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c index 7dd63da802..ad3931c112 100644 --- a/hw/intc/omap_intc.c +++ b/hw/intc/omap_intc.c @@ -392,6 +392,8 @@ static void omap_intc_class_init(ObjectClass *klass, void *data) k->init = omap_intc_init; dc->reset = omap_inth_reset; dc->props = omap_intc_properties; + /* Reason: pointer property "clk" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap_intc_info = { @@ -637,6 +639,8 @@ static void omap2_intc_class_init(ObjectClass *klass, void *data) k->init = omap2_intc_init; dc->reset = omap_inth_reset; dc->props = omap2_intc_properties; + /* Reason: pointer property "iclk", "fclk" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap2_intc_info = { diff --git a/hw/intc/pl190.c b/hw/intc/pl190.c index 329680da3a..2bf359a76b 100644 --- a/hw/intc/pl190.c +++ b/hw/intc/pl190.c @@ -273,7 +273,6 @@ static void pl190_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = pl190_init; - dc->no_user = 1; dc->reset = pl190_reset; dc->vmsd = &vmstate_pl190; } diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c index 9e104eb9a7..55d01008d3 100644 --- a/hw/isa/isa-bus.c +++ b/hw/isa/isa-bus.c @@ -197,7 +197,6 @@ static void isabus_bridge_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->fw_name = "isa"; - dc->no_user = 1; } static const TypeInfo isabus_bridge_info = { diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 19b2198fa6..51ce12dad6 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -644,14 +644,17 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data) dc->reset = ich9_lpc_reset; k->init = ich9_lpc_initfn; dc->vmsd = &vmstate_ich9_lpc; - dc->no_user = 1; k->config_write = ich9_lpc_config_write; dc->desc = "ICH9 LPC bridge"; k->vendor_id = PCI_VENDOR_ID_INTEL; k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8; k->revision = ICH9_A2_LPC_REVISION; k->class_id = PCI_CLASS_BRIDGE_ISA; - + /* + * Reason: part of ICH9 southbridge, needs to be wired up by + * pc_q35_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo ich9_lpc_info = { diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 1a1d4518ce..def6fe3a0f 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -113,8 +113,12 @@ static void piix4_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0; k->class_id = PCI_CLASS_BRIDGE_ISA; dc->desc = "ISA bridge"; - dc->no_user = 1; dc->vmsd = &vmstate_piix4; + /* + * Reason: part of PIIX4 southbridge, needs to be wired up, + * e.g. by mips_malta_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo piix4_info = { diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 5fb808630f..e639357db3 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -480,8 +480,12 @@ static void via_class_init(ObjectClass *klass, void *data) k->class_id = PCI_CLASS_BRIDGE_ISA; k->revision = 0x40; dc->desc = "ISA bridge"; - dc->no_user = 1; dc->vmsd = &vmstate_via; + /* + * Reason: part of VIA VT82C686 southbridge, needs to be wired up, + * e.g. by mips_fulong2e_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo via_info = { diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 3da2e67098..6398514c99 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -1151,12 +1151,18 @@ static int gt64120_pci_init(PCIDevice *d) static void gt64120_pci_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = gt64120_pci_init; k->vendor_id = PCI_VENDOR_ID_MARVELL; k->device_id = PCI_DEVICE_ID_MARVELL_GT6412X; k->revision = 0x10; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo gt64120_pci_info = { diff --git a/hw/misc/arm_l2x0.c b/hw/misc/arm_l2x0.c index 8e192cdf83..9e220c9a56 100644 --- a/hw/misc/arm_l2x0.c +++ b/hw/misc/arm_l2x0.c @@ -179,7 +179,6 @@ static void l2x0_class_init(ObjectClass *klass, void *data) k->init = l2x0_priv_init; dc->vmsd = &vmstate_l2x0; - dc->no_user = 1; dc->props = l2x0_properties; dc->reset = l2x0_priv_reset; } diff --git a/hw/misc/exynos4210_pmu.c b/hw/misc/exynos4210_pmu.c index cbf0795c0a..5ec14d1c86 100644 --- a/hw/misc/exynos4210_pmu.c +++ b/hw/misc/exynos4210_pmu.c @@ -383,8 +383,7 @@ static const Exynos4210PmuReg exynos4210_pmu_regs[] = { {"GPS_ALIVE_OPTION", GPS_ALIVE_OPTION, 0x00000001}, }; -#define PMU_NUM_OF_REGISTERS \ - (sizeof(exynos4210_pmu_regs) / sizeof(Exynos4210PmuReg)) +#define PMU_NUM_OF_REGISTERS ARRAY_SIZE(exynos4210_pmu_regs) #define TYPE_EXYNOS4210_PMU "exynos4210.pmu" #define EXYNOS4210_PMU(obj) \ diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c index 0b5a5644e4..cd5716a46d 100644 --- a/hw/misc/vmport.c +++ b/hw/misc/vmport.c @@ -162,7 +162,8 @@ static void vmport_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = vmport_realizefn; - dc->no_user = 1; + /* Reason: realize sets global port_state */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo vmport_info = { diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c index 78ebbbca72..6a3c86db48 100644 --- a/hw/net/etraxfs_eth.c +++ b/hw/net/etraxfs_eth.c @@ -646,6 +646,8 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data) k->init = fs_eth_init; dc->props = etraxfs_eth_properties; + /* Reason: pointer properties "dma_out", "dma_in" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo etraxfs_eth_info = { diff --git a/hw/net/lance.c b/hw/net/lance.c index e339f029b7..fe18564e1e 100644 --- a/hw/net/lance.c +++ b/hw/net/lance.c @@ -161,6 +161,8 @@ static void lance_class_init(ObjectClass *klass, void *data) dc->reset = lance_reset; dc->vmsd = &vmstate_lance; dc->props = lance_properties; + /* Reason: pointer property "dma" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo lance_info = { diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index f5dc3ea845..ee96c1681b 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -599,7 +599,6 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = fw_cfg_realize; - dc->no_user = 1; dc->reset = fw_cfg_reset; dc->vmsd = &vmstate_fw_cfg; dc->props = fw_cfg_properties; diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c index e5e3be829f..a6ca940d55 100644 --- a/hw/pci-bridge/dec.c +++ b/hw/pci-bridge/dec.c @@ -116,6 +116,7 @@ static int dec_21154_pci_host_init(PCIDevice *d) static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = dec_21154_pci_host_init; k->vendor_id = PCI_VENDOR_ID_DEC; @@ -123,6 +124,11 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data) k->revision = 0x02; k->class_id = PCI_CLASS_BRIDGE_PCI; k->is_bridge = 1; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo dec_21154_pci_host_info = { diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c index 92f289f8f9..1b399ddbc3 100644 --- a/hw/pci-host/apb.c +++ b/hw/pci-host/apb.c @@ -516,11 +516,17 @@ static int pbm_pci_host_init(PCIDevice *d) static void pbm_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = pbm_pci_host_init; k->vendor_id = PCI_VENDOR_ID_SUN; k->device_id = PCI_DEVICE_ID_SUN_SABRE; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo pbm_pci_host_info = { diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 5086d42c13..902441f10b 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -806,8 +806,12 @@ static void bonito_class_init(ObjectClass *klass, void *data) k->revision = 0x01; k->class_id = PCI_CLASS_BRIDGE_HOST; dc->desc = "Host bridge"; - dc->no_user = 1; dc->vmsd = &vmstate_bonito; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo bonito_info = { @@ -819,11 +823,9 @@ static const TypeInfo bonito_info = { static void bonito_pcihost_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = bonito_pcihost_initfn; - dc->no_user = 1; } static const TypeInfo bonito_pcihost_info = { diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index 75b60d36ac..6c7cfdbeb2 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -130,7 +130,11 @@ static void grackle_pci_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; - dc->no_user = 1; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo grackle_pci_info = { @@ -143,10 +147,8 @@ static const TypeInfo grackle_pci_info = { static void pci_grackle_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - DeviceClass *dc = DEVICE_CLASS(klass); k->init = pci_grackle_init_device; - dc->no_user = 1; } static const TypeInfo grackle_pci_host_info = { diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 63be7f6cee..cc97150a90 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -635,7 +635,6 @@ static void piix3_class_init(ObjectClass *klass, void *data) dc->desc = "ISA bridge"; dc->vmsd = &vmstate_piix3; - dc->no_user = 1, k->no_hotplug = 1; k->init = piix3_initfn; k->config_write = piix3_write_config; @@ -643,6 +642,11 @@ static void piix3_class_init(ObjectClass *klass, void *data) /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; k->class_id = PCI_CLASS_BRIDGE_ISA; + /* + * Reason: part of PIIX3 southbridge, needs to be wired up by + * pc_piix.c's pc_init1() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo piix3_info = { @@ -659,7 +663,6 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data) dc->desc = "ISA bridge"; dc->vmsd = &vmstate_piix3; - dc->no_user = 1; k->no_hotplug = 1; k->init = piix3_initfn; k->config_write = piix3_write_config_xen; @@ -667,6 +670,11 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data) /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; k->class_id = PCI_CLASS_BRIDGE_ISA; + /* + * Reason: part of PIIX3 southbridge, needs to be wired up by + * pc_piix.c's pc_init1() + */ + dc->cannot_instantiate_with_device_add_yet = true; }; static const TypeInfo piix3_xen_info = { @@ -689,8 +697,12 @@ static void i440fx_class_init(ObjectClass *klass, void *data) k->revision = 0x02; k->class_id = PCI_CLASS_BRIDGE_HOST; dc->desc = "Host bridge"; - dc->no_user = 1; dc->vmsd = &vmstate_i440fx; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo i440fx_info = { @@ -727,7 +739,6 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data) hc->root_bus_path = i440fx_pcihost_root_bus_path; dc->realize = i440fx_pcihost_realize; dc->fw_name = "pci"; - dc->no_user = 1; dc->props = i440fx_props; } diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c index f00793d819..c80b7cb2f5 100644 --- a/hw/pci-host/ppce500.c +++ b/hw/pci-host/ppce500.c @@ -387,6 +387,11 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_MPC8533E; k->class_id = PCI_CLASS_PROCESSOR_POWERPC; dc->desc = "Host bridge"; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo e500_host_bridge_info = { diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index 0e71fdbfb1..042dc8f225 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -198,7 +198,11 @@ static void raven_class_init(ObjectClass *klass, void *data) k->class_id = PCI_CLASS_BRIDGE_HOST; dc->desc = "PReP Host Bridge - Motorola Raven"; dc->vmsd = &vmstate_raven; - dc->no_user = 1; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo raven_info = { @@ -215,7 +219,6 @@ static void raven_pcihost_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); dc->realize = raven_pcihost_realizefn; dc->fw_name = "pci"; - dc->no_user = 1; } static const TypeInfo raven_pcihost_info = { diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 81c82404d6..4bc2e0118e 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -403,6 +403,11 @@ static void mch_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_Q35_MCH; k->revision = MCH_HOST_BRIDGE_REVISION_DEFAULT; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo mch_info = { diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index adc1d89010..e72fe2a70b 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -351,12 +351,18 @@ static int unin_internal_pci_host_init(PCIDevice *d) static void unin_main_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = unin_main_pci_host_init; k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo unin_main_pci_host_info = { @@ -369,12 +375,18 @@ static const TypeInfo unin_main_pci_host_info = { static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = u3_agp_pci_host_init; k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo u3_agp_pci_host_info = { @@ -387,12 +399,18 @@ static const TypeInfo u3_agp_pci_host_info = { static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = unin_agp_pci_host_init; k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo unin_agp_pci_host_info = { @@ -405,12 +423,18 @@ static const TypeInfo unin_agp_pci_host_info = { static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = unin_internal_pci_host_init; k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo unin_internal_pci_host_info = { diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c index 6b28929d26..71ff0de303 100644 --- a/hw/pci-host/versatile.c +++ b/hw/pci-host/versatile.c @@ -467,11 +467,17 @@ static int versatile_pci_host_init(PCIDevice *d) static void versatile_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = versatile_pci_host_init; k->vendor_id = PCI_VENDOR_ID_XILINX; k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30; k->class_id = PCI_CLASS_PROCESSOR_CO; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo versatile_pci_host_info = { diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index f72872ebcf..355c3e1b06 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -391,7 +391,7 @@ void pci_bridge_exitfn(PCIDevice *pci_dev) pci_bridge_region_cleanup(s, s->windows); memory_region_destroy(&s->address_space_mem); memory_region_destroy(&s->address_space_io); - /* qbus_free() is called automatically during device deletion */ + /* object_unparent() is called automatically during device deletion */ } /* diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c index d2d6f65e6c..4cb78518a3 100644 --- a/hw/ppc/ppc4xx_pci.c +++ b/hw/ppc/ppc4xx_pci.c @@ -380,6 +380,11 @@ static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data) k->vendor_id = PCI_VENDOR_ID_IBM; k->device_id = PCI_DEVICE_ID_IBM_440GX; k->class_id = PCI_CLASS_BRIDGE_OTHER; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo ppc4xx_host_bridge_info = { diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index fee6195f95..4e33f462d9 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -528,11 +528,9 @@ static int spapr_vio_bridge_init(SysBusDevice *dev) static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = spapr_vio_bridge_init; - dc->no_user = 1; } static const TypeInfo spapr_vio_bridge_info = { diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 65d39da314..1a6397b88e 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -182,7 +182,6 @@ static void s390_ipl_class_init(ObjectClass *klass, void *data) k->init = s390_ipl_init; dc->props = s390_ipl_properties; dc->reset = s390_ipl_reset; - dc->no_user = 1; } static const TypeInfo s390_ipl_info = { diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 6a831114da..46c5ff1898 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -676,11 +676,9 @@ static int s390_virtio_bridge_init(SysBusDevice *dev) static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = s390_virtio_bridge_init; - dc->no_user = 1; } static const TypeInfo s390_virtio_bridge_info = { diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index ecc80ecaf7..4b6250dda9 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1283,11 +1283,9 @@ static int virtual_css_bridge_init(SysBusDevice *dev) static void virtual_css_bridge_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = virtual_css_bridge_init; - dc->no_user = 1; } static const TypeInfo virtual_css_bridge_info = { diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c index c35896d28c..462558b76d 100644 --- a/hw/sd/pl181.c +++ b/hw/sd/pl181.c @@ -506,7 +506,6 @@ static void pl181_class_init(ObjectClass *klass, void *data) sdc->init = pl181_init; k->vmsd = &vmstate_pl181; k->reset = pl181_reset; - k->no_user = 1; } static const TypeInfo pl181_info = { diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c index e81176a11e..a2f6d9e0b6 100644 --- a/hw/sh4/sh_pci.c +++ b/hw/sh4/sh_pci.c @@ -162,10 +162,16 @@ static int sh_pci_host_init(PCIDevice *d) static void sh_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = sh_pci_host_init; k->vendor_id = PCI_VENDOR_ID_HITACHI; k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo sh_pci_host_info = { diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c index d9f9494f26..35a0a2356f 100644 --- a/hw/timer/arm_mptimer.c +++ b/hw/timer/arm_mptimer.c @@ -274,7 +274,6 @@ static void arm_mptimer_class_init(ObjectClass *klass, void *data) dc->realize = arm_mptimer_realize; dc->vmsd = &vmstate_arm_mptimer; dc->reset = arm_mptimer_reset; - dc->no_user = 1; dc->props = arm_mptimer_properties; } diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index bb3bf98745..2fbbeb1735 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -765,7 +765,6 @@ static void hpet_device_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = hpet_realize; - dc->no_user = 1; dc->reset = hpet_reset; dc->vmsd = &vmstate_hpet; dc->props = hpet_device_properties; diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c index e8fb971488..9db5c9d129 100644 --- a/hw/timer/i8254_common.c +++ b/hw/timer/i8254_common.c @@ -282,7 +282,12 @@ static void pit_common_class_init(ObjectClass *klass, void *data) dc->realize = pit_common_realize; dc->vmsd = &vmstate_pit_common; - dc->no_user = 1; + /* + * Reason: unlike ordinary ISA devices, the PIT may need to be + * wired to the HPET, and because of that, some wiring is always + * done by board code. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo pit_common_type = { diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c index be0592b53d..3cfb18a8b3 100644 --- a/hw/timer/m48t59.c +++ b/hw/timer/m48t59.c @@ -750,9 +750,10 @@ static void m48t59_isa_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = m48t59_isa_realize; - dc->no_user = 1; dc->reset = m48t59_reset_isa; dc->props = m48t59_isa_properties; + /* Reason: needs to be wired up by m48t59_init_isa() */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo m48t59_isa_info = { diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index b0116381c0..6fb124fead 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -899,9 +899,10 @@ static void rtc_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = rtc_realizefn; - dc->no_user = 1; dc->vmsd = &vmstate_rtc; dc->props = mc146818rtc_properties; + /* Reason: needs to be wired up by rtc_init() */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo mc146818rtc_info = { diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c index 65928a4819..34d9b44e7e 100644 --- a/hw/timer/pl031.c +++ b/hw/timer/pl031.c @@ -251,7 +251,6 @@ static void pl031_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = pl031_init; - dc->no_user = 1; dc->vmsd = &vmstate_pl031; } diff --git a/hw/xen/xen_apic.c b/hw/xen/xen_apic.c index 9f91e0f0c9..63bb7f77c6 100644 --- a/hw/xen/xen_apic.c +++ b/hw/xen/xen_apic.c @@ -36,8 +36,10 @@ static const MemoryRegionOps xen_apic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void xen_apic_init(APICCommonState *s) +static void xen_apic_realize(DeviceState *dev, Error **errp) { + APICCommonState *s = APIC_COMMON(dev); + memory_region_init_io(&s->io_memory, OBJECT(s), &xen_apic_io_ops, s, "xen-apic-msi", APIC_SPACE_SIZE); @@ -72,7 +74,7 @@ static void xen_apic_class_init(ObjectClass *klass, void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); - k->init = xen_apic_init; + k->realize = xen_apic_realize; k->set_base = xen_apic_set_base; k->set_tpr = xen_apic_set_tpr; k->get_tpr = xen_apic_get_tpr; diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h index a4e1a66264..7ca330a61f 100644 --- a/include/hw/arm/pxa.h +++ b/include/hw/arm/pxa.h @@ -102,15 +102,15 @@ void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq); /* pxa2xx_keypad.c */ struct keymap { - int column; - int row; + int8_t column; + int8_t row; }; typedef struct PXA2xxKeyPadState PXA2xxKeyPadState; PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem, hwaddr base, qemu_irq irq); -void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map, - int size); +void pxa27x_register_keypad(PXA2xxKeyPadState *kp, + const struct keymap *map, int size); /* pxa2xx.c */ typedef struct PXA2xxI2CState PXA2xxI2CState; diff --git a/include/hw/cpu/icc_bus.h b/include/hw/cpu/icc_bus.h index b5500708dc..98a979fa1c 100644 --- a/include/hw/cpu/icc_bus.h +++ b/include/hw/cpu/icc_bus.h @@ -66,7 +66,7 @@ typedef struct ICCDeviceClass { DeviceClass parent_class; /*< public >*/ - int (*init)(ICCDevice *dev); /* TODO replace with QOM realize */ + DeviceRealize realize; } ICCDeviceClass; #define TYPE_ICC_DEVICE "icc-device" diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h index 1b0a7fbfad..70542a6f43 100644 --- a/include/hw/i386/apic_internal.h +++ b/include/hw/i386/apic_internal.h @@ -80,7 +80,7 @@ typedef struct APICCommonClass { ICCDeviceClass parent_class; - void (*init)(APICCommonState *s); + DeviceRealize realize; void (*set_base)(APICCommonState *s, uint64_t val); void (*set_tpr)(APICCommonState *s, uint8_t val); uint8_t (*get_tpr)(APICCommonState *s); diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h index 25576c819e..3be3352185 100644 --- a/include/hw/i386/ioapic_internal.h +++ b/include/hw/i386/ioapic_internal.h @@ -83,7 +83,8 @@ typedef struct IOAPICCommonState IOAPICCommonState; typedef struct IOAPICCommonClass { SysBusDeviceClass parent_class; - void (*init)(IOAPICCommonState *s, int instance_no); + + DeviceRealize realize; void (*pre_save)(IOAPICCommonState *s); void (*post_load)(IOAPICCommonState *s); } IOAPICCommonClass; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index f2043a69c2..651c3e54ee 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -97,7 +97,18 @@ typedef struct DeviceClass { const char *fw_name; const char *desc; Property *props; - int no_user; + + /* + * Shall we hide this device model from -device / device_add? + * All devices should support instantiation with device_add, and + * this flag should not exist. But we're not there, yet. Some + * devices fail to instantiate with cryptic error messages. + * Others instantiate, but don't work. Exposing users to such + * behavior would be cruel; this flag serves to protect them. It + * should never be set without a comment explaining why it is set. + * TODO remove once we're there + */ + bool cannot_instantiate_with_device_add_yet; /* callbacks */ void (*reset)(DeviceState *dev); @@ -272,8 +283,6 @@ void qdev_reset_all(DeviceState *dev); void qbus_reset_all(BusState *bus); void qbus_reset_all_fn(void *opaque); -void qbus_free(BusState *bus); - /* This should go away once we get rid of the NULL bus hack */ BusState *sysbus_get_default(void); diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 692f82e935..77c6f7c037 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -122,8 +122,25 @@ extern PropertyInfo qdev_prop_arraylen; #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) +/* + * Please avoid pointer properties. If you must use them, you must + * cover them in their device's class init function as follows: + * + * - If the property must be set, the device cannot be used with + * device_add, so add code like this: + * |* Reason: pointer property "NAME-OF-YOUR-PROP" *| + * DeviceClass *dc = DEVICE_CLASS(class); + * dc->cannot_instantiate_with_device_add_yet = true; + * + * - If the property may safely remain null, document it like this: + * |* + * * Note: pointer property "interrupt_vector" may remain null, thus + * * no need for dc->cannot_instantiate_with_device_add_yet = true; + * *| + */ #define DEFINE_PROP_PTR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) + #define DEFINE_PROP_CHR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*) #define DEFINE_PROP_STRING(_n, _s, _f) \ diff --git a/include/qom/object.h b/include/qom/object.h index a275db2092..e0ff212cb6 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -358,7 +358,8 @@ struct ObjectClass Type type; GSList *interfaces; - const char *cast_cache[OBJECT_CLASS_CAST_CACHE]; + const char *object_cast_cache[OBJECT_CLASS_CAST_CACHE]; + const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE]; ObjectUnparent *unparent; }; @@ -535,6 +536,7 @@ struct InterfaceClass ObjectClass parent_class; /*< private >*/ ObjectClass *concrete_class; + Type interface_type; }; #define TYPE_INTERFACE "interface" diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 8dd424dadd..5902f162b4 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1998,8 +1998,7 @@ give_up: free(syms); } -int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info) +int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) { struct image_info interp_info; struct elfhdr elf_ex; diff --git a/linux-user/flatload.c b/linux-user/flatload.c index ceb89bb6ea..566a7a87a3 100644 --- a/linux-user/flatload.c +++ b/linux-user/flatload.c @@ -704,8 +704,7 @@ static int load_flat_shared_library(int id, struct lib_info *libs) #endif /* CONFIG_BINFMT_SHARED_FLAT */ -int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info) +int load_flt_binary(struct linux_binprm *bprm, struct image_info *info) { struct lib_info libinfo[MAX_SHARED_LIBS]; abi_ulong p = bprm->p; diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index a1fe5ed9ae..f2997c2f4b 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -154,13 +154,13 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp, && bprm->buf[1] == 'E' && bprm->buf[2] == 'L' && bprm->buf[3] == 'F') { - retval = load_elf_binary(bprm, regs, infop); + retval = load_elf_binary(bprm, infop); #if defined(TARGET_HAS_BFLT) } else if (bprm->buf[0] == 'b' && bprm->buf[1] == 'F' && bprm->buf[2] == 'L' && bprm->buf[3] == 'T') { - retval = load_flt_binary(bprm,regs,infop); + retval = load_flt_binary(bprm, infop); #endif } else { return -ENOEXEC; diff --git a/linux-user/qemu.h b/linux-user/qemu.h index e2717e0775..c2f74f33d6 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -178,10 +178,8 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp, struct target_pt_regs * regs, struct image_info *infop, struct linux_binprm *); -int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); -int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); +int load_elf_binary(struct linux_binprm *bprm, struct image_info *info); +int load_flt_binary(struct linux_binprm *bprm, struct image_info *info); abi_long memcpy_to_target(abi_ulong dest, const void *src, unsigned long len); diff --git a/linux-user/signal.c b/linux-user/signal.c index 6c74b18196..01d7c393df 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -2543,9 +2543,9 @@ void sparc64_set_context(CPUSPARCState *env) abi_ulong *src, *dst; src = ucp->tuc_sigmask.sig; dst = target_set.sig; - for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); - i++, dst++, src++) + for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) { err |= __get_user(*dst, src); + } if (err) goto do_sigsegv; } @@ -2648,9 +2648,9 @@ void sparc64_get_context(CPUSPARCState *env) abi_ulong *src, *dst; src = target_set.sig; dst = ucp->tuc_sigmask.sig; - for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); - i++, dst++, src++) + for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) { err |= __put_user(*src, dst); + } if (err) goto do_sigsegv; } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index efd1453987..0ac05b85f2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2245,6 +2245,22 @@ static abi_long do_socketcall(int num, abi_ulong vptr) ret = do_accept4(sockfd, target_addr, target_addrlen, 0); } break; + case SOCKOP_accept4: + { + abi_ulong sockfd; + abi_ulong target_addr, target_addrlen; + abi_ulong flags; + + if (get_user_ual(sockfd, vptr) + || get_user_ual(target_addr, vptr + n) + || get_user_ual(target_addrlen, vptr + 2 * n) + || get_user_ual(flags, vptr + 3 * n)) { + return -TARGET_EFAULT; + } + + ret = do_accept4(sockfd, target_addr, target_addrlen, flags); + } + break; case SOCKOP_getsockname: { abi_ulong sockfd; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index cf08db5a23..ae30476217 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -27,6 +27,7 @@ #define SOCKOP_getsockopt 15 #define SOCKOP_sendmsg 16 #define SOCKOP_recvmsg 17 +#define SOCKOP_accept4 18 #define IPCOP_semop 1 #define IPCOP_semget 2 @@ -856,7 +856,7 @@ static int net_host_check_device(const char *device) ,"vde" #endif }; - for (i = 0; i < sizeof(valid_param_list) / sizeof(char *); i++) { + for (i = 0; i < ARRAY_SIZE(valid_param_list); i++) { if (!strncmp(valid_param_list[i], device, strlen(valid_param_list[i]))) return 1; diff --git a/qdev-monitor.c b/qdev-monitor.c index dc37a43dd9..ef63cbd7bb 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -87,7 +87,7 @@ static void qdev_print_devinfo(DeviceClass *dc) if (dc->desc) { error_printf(", desc \"%s\"", dc->desc); } - if (dc->no_user) { + if (dc->cannot_instantiate_with_device_add_yet) { error_printf(", no-user"); } error_printf("\n"); @@ -127,7 +127,8 @@ static void qdev_print_devinfos(bool show_no_user) if ((i < DEVICE_CATEGORY_MAX ? !test_bit(i, dc->categories) : !bitmap_empty(dc->categories, DEVICE_CATEGORY_MAX)) - || (!show_no_user && dc->no_user)) { + || (!show_no_user + && dc->cannot_instantiate_with_device_add_yet)) { continue; } if (!cat_printed) { @@ -477,8 +478,9 @@ DeviceState *qdev_device_add(QemuOpts *opts) } } - if (!oc) { - qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type"); + if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) { + qerror_report(ERROR_CLASS_GENERIC_ERROR, + "'%s' is not a valid device model name", driver); return NULL; } @@ -489,6 +491,11 @@ DeviceState *qdev_device_add(QemuOpts *opts) } dc = DEVICE_CLASS(oc); + if (dc->cannot_instantiate_with_device_add_yet) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", + "pluggable device type"); + return NULL; + } /* find bus */ path = qemu_opt_get(opts, "bus"); diff --git a/qemu-char.c b/qemu-char.c index 418dc69d39..30c5a6afd0 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1975,8 +1975,7 @@ static void win_stdio_wait_func(void *opaque) DWORD dwSize; int i; - ret = ReadConsoleInput(stdio->hStdIn, buf, sizeof(buf) / sizeof(*buf), - &dwSize); + ret = ReadConsoleInput(stdio->hStdIn, buf, ARRAY_SIZE(buf), &dwSize); if (!ret) { /* Avoid error storm */ diff --git a/qemu-options.hx b/qemu-options.hx index bcfe9eaa3e..56e5fdf1e0 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2419,6 +2419,8 @@ vc:80Cx24C No device is allocated. @item null void device +@item chardev:@var{id} +Use a named character device defined with the @code{-chardev} option. @item /dev/XXX [Linux only] Use host tty, e.g. @file{/dev/ttyS0}. The host serial port parameters are set according to the emulated ones. diff --git a/qemu-seccomp.c b/qemu-seccomp.c index cf07869599..b7c125364c 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -231,6 +231,7 @@ int seccomp_start(void) ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) { + rc = -1; goto seccomp_return; } @@ -254,7 +254,11 @@ static void cpu_class_init(ObjectClass *klass, void *data) k->gdb_read_register = cpu_common_gdb_read_register; k->gdb_write_register = cpu_common_gdb_write_register; dc->realize = cpu_common_realizefn; - dc->no_user = 1; + /* + * Reason: CPUs still need special care by board code: wiring up + * IRQs, adding reset handlers, halting non-first CPUs, ... + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo cpu_type_info = { diff --git a/qom/object.c b/qom/object.c index fc19cf676a..2aab30b32f 100644 --- a/qom/object.c +++ b/qom/object.c @@ -78,8 +78,11 @@ static GHashTable *type_table_get(void) return type_table; } +static bool enumerating_types; + static void type_table_add(TypeImpl *ti) { + assert(!enumerating_types); g_hash_table_insert(type_table_get(), (void *)ti->name, ti); } @@ -88,7 +91,7 @@ static TypeImpl *type_table_lookup(const char *name) return g_hash_table_lookup(type_table_get(), name); } -static TypeImpl *type_register_internal(const TypeInfo *info) +static TypeImpl *type_new(const TypeInfo *info) { TypeImpl *ti = g_malloc0(sizeof(*ti)); int i; @@ -122,8 +125,15 @@ static TypeImpl *type_register_internal(const TypeInfo *info) } ti->num_interfaces = i; - type_table_add(ti); + return ti; +} + +static TypeImpl *type_register_internal(const TypeInfo *info) +{ + TypeImpl *ti; + ti = type_new(info); + type_table_add(ti); return ti; } @@ -206,22 +216,25 @@ static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) static void type_initialize(TypeImpl *ti); -static void type_initialize_interface(TypeImpl *ti, const char *parent) +static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type, + TypeImpl *parent_type) { InterfaceClass *new_iface; TypeInfo info = { }; TypeImpl *iface_impl; - info.parent = parent; - info.name = g_strdup_printf("%s::%s", ti->name, info.parent); + info.parent = parent_type->name; + info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name); info.abstract = true; - iface_impl = type_register(&info); + iface_impl = type_new(&info); + iface_impl->parent_type = parent_type; type_initialize(iface_impl); g_free((char *)info.name); new_iface = (InterfaceClass *)iface_impl->class; new_iface->concrete_class = ti->class; + new_iface->interface_type = interface_type; ti->class->interfaces = g_slist_append(ti->class->interfaces, iface_impl->class); @@ -251,8 +264,10 @@ static void type_initialize(TypeImpl *ti) ti->class->interfaces = NULL; for (e = parent->class->interfaces; e; e = e->next) { - ObjectClass *iface = e->data; - type_initialize_interface(ti, object_class_get_name(iface)); + InterfaceClass *iface = e->data; + ObjectClass *klass = OBJECT_CLASS(iface); + + type_initialize_interface(ti, iface->interface_type, klass->type); } for (i = 0; i < ti->num_interfaces; i++) { @@ -269,7 +284,7 @@ static void type_initialize(TypeImpl *ti) continue; } - type_initialize_interface(ti, ti->interfaces[i].typename); + type_initialize_interface(ti, t, t); } } @@ -285,8 +300,6 @@ static void type_initialize(TypeImpl *ti) if (ti->class_init) { ti->class_init(ti->class, ti->class_data); } - - } static void object_init_with_type(Object *obj, TypeImpl *ti) @@ -458,7 +471,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename, Object *inst; for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) { - if (obj->class->cast_cache[i] == typename) { + if (obj->class->object_cast_cache[i] == typename) { goto out; } } @@ -475,9 +488,10 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename, if (obj && obj == inst) { for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { - obj->class->cast_cache[i - 1] = obj->class->cast_cache[i]; + obj->class->object_cast_cache[i - 1] = + obj->class->object_cast_cache[i]; } - obj->class->cast_cache[i - 1] = typename; + obj->class->object_cast_cache[i - 1] = typename; } out: @@ -547,7 +561,7 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, int i; for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) { - if (class->cast_cache[i] == typename) { + if (class->class_cast_cache[i] == typename) { ret = class; goto out; } @@ -568,9 +582,9 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, #ifdef CONFIG_QOM_CAST_DEBUG if (class && ret == class) { for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { - class->cast_cache[i - 1] = class->cast_cache[i]; + class->class_cast_cache[i - 1] = class->class_cast_cache[i]; } - class->cast_cache[i - 1] = typename; + class->class_cast_cache[i - 1] = typename; } out: #endif @@ -659,7 +673,9 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), { OCFData data = { fn, implements_type, include_abstract, opaque }; + enumerating_types = true; g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); + enumerating_types = false; } int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 43ca5722e7..f1307eb488 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -73,7 +73,7 @@ * significant half of a uint64_t struct member. */ #ifdef HOST_WORDS_BIGENDIAN -#define offsetoflow32(S, M) (offsetof(S, M + sizeof(uint32_t)) +#define offsetoflow32(S, M) offsetof(S, M + sizeof(uint32_t)) #else #define offsetoflow32(S, M) offsetof(S, M) #endif diff --git a/target-i386/helper.c b/target-i386/helper.c index 7c196ffc42..ed965d634d 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -531,6 +531,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, if (!(env->cr[0] & CR0_PG_MASK)) { pte = addr; +#ifdef TARGET_X86_64 + if (!(env->hflags & HF_LMA_MASK)) { + /* Without long mode we can only address 32bits in real mode */ + pte = (uint32_t)pte; + } +#endif virt_addr = addr & TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; page_size = 4096; diff --git a/target-i386/translate.c b/target-i386/translate.c index 7916e5b1f6..b0f227915a 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -85,7 +85,8 @@ typedef struct DisasContext { /* current insn context */ int override; /* -1 if no override */ int prefix; - int aflag, dflag; + TCGMemOp aflag; + TCGMemOp dflag; target_ulong pc; /* pc = eip + cs_base */ int is_jmp; /* 1 = means jump (stop translation), 2 means CPU static state change (stop translation) */ @@ -126,7 +127,7 @@ typedef struct DisasContext { static void gen_eob(DisasContext *s); static void gen_jmp(DisasContext *s, target_ulong eip); static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num); -static void gen_op(DisasContext *s1, int op, int ot, int d); +static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d); /* i386 arith/logic operations */ enum { @@ -163,14 +164,6 @@ enum { JCC_LE, }; -/* operand size */ -enum { - OT_BYTE = 0, - OT_WORD, - OT_LONG, - OT_QUAD, -}; - enum { /* I386 int registers */ OR_EAX, /* MUST be even numbered */ @@ -260,73 +253,6 @@ static void gen_update_cc_op(DisasContext *s) } } -static inline void gen_op_movl_T0_0(void) -{ - tcg_gen_movi_tl(cpu_T[0], 0); -} - -static inline void gen_op_movl_T0_im(int32_t val) -{ - tcg_gen_movi_tl(cpu_T[0], val); -} - -static inline void gen_op_movl_T0_imu(uint32_t val) -{ - tcg_gen_movi_tl(cpu_T[0], val); -} - -static inline void gen_op_movl_T1_im(int32_t val) -{ - tcg_gen_movi_tl(cpu_T[1], val); -} - -static inline void gen_op_movl_T1_imu(uint32_t val) -{ - tcg_gen_movi_tl(cpu_T[1], val); -} - -static inline void gen_op_movl_A0_im(uint32_t val) -{ - tcg_gen_movi_tl(cpu_A0, val); -} - -#ifdef TARGET_X86_64 -static inline void gen_op_movq_A0_im(int64_t val) -{ - tcg_gen_movi_tl(cpu_A0, val); -} -#endif - -static inline void gen_movtl_T0_im(target_ulong val) -{ - tcg_gen_movi_tl(cpu_T[0], val); -} - -static inline void gen_movtl_T1_im(target_ulong val) -{ - tcg_gen_movi_tl(cpu_T[1], val); -} - -static inline void gen_op_andl_T0_ffff(void) -{ - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff); -} - -static inline void gen_op_andl_T0_im(uint32_t val) -{ - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val); -} - -static inline void gen_op_movl_T0_T1(void) -{ - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); -} - -static inline void gen_op_andl_A0_ffff(void) -{ - tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff); -} - #ifdef TARGET_X86_64 #define NB_OP_SIZES 4 @@ -370,66 +296,71 @@ static inline bool byte_reg_is_xH(int reg) return true; } -static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0) +/* Select the size of a push/pop operation. */ +static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot) +{ + if (CODE64(s)) { + return ot == MO_16 ? MO_16 : MO_64; + } else { + return ot; + } +} + +/* Select only size 64 else 32. Used for SSE operand sizes. */ +static inline TCGMemOp mo_64_32(TCGMemOp ot) { - switch(ot) { - case OT_BYTE: - if (!byte_reg_is_xH(reg)) { - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8); - } else { - tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8); - } - break; - case OT_WORD: - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16); - break; - default: /* XXX this shouldn't be reached; abort? */ - case OT_LONG: - /* For x86_64, this sets the higher half of register to zero. - For i386, this is equivalent to a mov. */ - tcg_gen_ext32u_tl(cpu_regs[reg], t0); - break; #ifdef TARGET_X86_64 - case OT_QUAD: - tcg_gen_mov_tl(cpu_regs[reg], t0); - break; + return ot == MO_64 ? MO_64 : MO_32; +#else + return MO_32; #endif - } } -static inline void gen_op_mov_reg_T0(int ot, int reg) +/* Select size 8 if lsb of B is clear, else OT. Used for decoding + byte vs word opcodes. */ +static inline TCGMemOp mo_b_d(int b, TCGMemOp ot) { - gen_op_mov_reg_v(ot, reg, cpu_T[0]); + return b & 1 ? ot : MO_8; } -static inline void gen_op_mov_reg_T1(int ot, int reg) +/* Select size 8 if lsb of B is clear, else OT capped at 32. + Used for decoding operand size of port opcodes. */ +static inline TCGMemOp mo_b_d32(int b, TCGMemOp ot) { - gen_op_mov_reg_v(ot, reg, cpu_T[1]); + return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8; } -static inline void gen_op_mov_reg_A0(int size, int reg) +static void gen_op_mov_reg_v(TCGMemOp ot, int reg, TCGv t0) { - switch(size) { - case OT_BYTE: - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_A0, 0, 16); + switch(ot) { + case MO_8: + if (!byte_reg_is_xH(reg)) { + tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8); + } else { + tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8); + } break; - default: /* XXX this shouldn't be reached; abort? */ - case OT_WORD: + case MO_16: + tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16); + break; + case MO_32: /* For x86_64, this sets the higher half of register to zero. For i386, this is equivalent to a mov. */ - tcg_gen_ext32u_tl(cpu_regs[reg], cpu_A0); + tcg_gen_ext32u_tl(cpu_regs[reg], t0); break; #ifdef TARGET_X86_64 - case OT_LONG: - tcg_gen_mov_tl(cpu_regs[reg], cpu_A0); + case MO_64: + tcg_gen_mov_tl(cpu_regs[reg], t0); break; #endif + default: + tcg_abort(); } } -static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg) +static inline void gen_op_mov_v_reg(TCGMemOp ot, TCGv t0, int reg) { - if (ot == OT_BYTE && byte_reg_is_xH(reg)) { + if (ot == MO_8 && byte_reg_is_xH(reg)) { tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8); tcg_gen_ext8u_tl(t0, t0); } else { @@ -437,11 +368,6 @@ static inline void gen_op_mov_v_reg(int ot, TCGv t0, int reg) } } -static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg) -{ - gen_op_mov_v_reg(ot, cpu_T[t_index], reg); -} - static inline void gen_op_movl_A0_reg(int reg) { tcg_gen_mov_tl(cpu_A0, cpu_regs[reg]); @@ -472,58 +398,21 @@ static void gen_add_A0_im(DisasContext *s, int val) gen_op_addl_A0_im(val); } -static inline void gen_op_addl_T0_T1(void) +static inline void gen_op_jmp_v(TCGv dest) { - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip)); } -static inline void gen_op_jmp_T0(void) +static inline void gen_op_add_reg_im(TCGMemOp size, int reg, int32_t val) { - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, eip)); + tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val); + gen_op_mov_reg_v(size, reg, cpu_tmp0); } -static inline void gen_op_add_reg_im(int size, int reg, int32_t val) +static inline void gen_op_add_reg_T0(TCGMemOp size, int reg) { - switch(size) { - case OT_BYTE: - tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val); - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16); - break; - case OT_WORD: - tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val); - /* For x86_64, this sets the higher half of register to zero. - For i386, this is equivalent to a nop. */ - tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0); - tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0); - break; -#ifdef TARGET_X86_64 - case OT_LONG: - tcg_gen_addi_tl(cpu_regs[reg], cpu_regs[reg], val); - break; -#endif - } -} - -static inline void gen_op_add_reg_T0(int size, int reg) -{ - switch(size) { - case OT_BYTE: - tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]); - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16); - break; - case OT_WORD: - tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]); - /* For x86_64, this sets the higher half of register to zero. - For i386, this is equivalent to a nop. */ - tcg_gen_ext32u_tl(cpu_tmp0, cpu_tmp0); - tcg_gen_mov_tl(cpu_regs[reg], cpu_tmp0); - break; -#ifdef TARGET_X86_64 - case OT_LONG: - tcg_gen_add_tl(cpu_regs[reg], cpu_regs[reg], cpu_T[0]); - break; -#endif - } + tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]); + gen_op_mov_reg_v(size, reg, cpu_tmp0); } static inline void gen_op_addl_A0_reg_sN(int shift, int reg) @@ -584,99 +473,29 @@ static inline void gen_op_addq_A0_reg_sN(int shift, int reg) } #endif -static inline void gen_op_lds_T0_A0(int idx) +static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0) { - int mem_index = (idx >> 2) - 1; - switch(idx & 3) { - case OT_BYTE: - tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index); - break; - case OT_WORD: - tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index); - break; - default: - case OT_LONG: - tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index); - break; - } + tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE); } -static inline void gen_op_ld_v(int idx, TCGv t0, TCGv a0) +static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0) { - int mem_index = (idx >> 2) - 1; - switch(idx & 3) { - case OT_BYTE: - tcg_gen_qemu_ld8u(t0, a0, mem_index); - break; - case OT_WORD: - tcg_gen_qemu_ld16u(t0, a0, mem_index); - break; - case OT_LONG: - tcg_gen_qemu_ld32u(t0, a0, mem_index); - break; - default: - case OT_QUAD: - /* Should never happen on 32-bit targets. */ -#ifdef TARGET_X86_64 - tcg_gen_qemu_ld64(t0, a0, mem_index); -#endif - break; - } + tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE); } -/* XXX: always use ldu or lds */ -static inline void gen_op_ld_T0_A0(int idx) +static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d) { - gen_op_ld_v(idx, cpu_T[0], cpu_A0); -} - -static inline void gen_op_ldu_T0_A0(int idx) -{ - gen_op_ld_v(idx, cpu_T[0], cpu_A0); -} - -static inline void gen_op_ld_T1_A0(int idx) -{ - gen_op_ld_v(idx, cpu_T[1], cpu_A0); -} - -static inline void gen_op_st_v(int idx, TCGv t0, TCGv a0) -{ - int mem_index = (idx >> 2) - 1; - switch(idx & 3) { - case OT_BYTE: - tcg_gen_qemu_st8(t0, a0, mem_index); - break; - case OT_WORD: - tcg_gen_qemu_st16(t0, a0, mem_index); - break; - case OT_LONG: - tcg_gen_qemu_st32(t0, a0, mem_index); - break; - default: - case OT_QUAD: - /* Should never happen on 32-bit targets. */ -#ifdef TARGET_X86_64 - tcg_gen_qemu_st64(t0, a0, mem_index); -#endif - break; + if (d == OR_TMP0) { + gen_op_st_v(s, idx, cpu_T[0], cpu_A0); + } else { + gen_op_mov_reg_v(idx, d, cpu_T[0]); } } -static inline void gen_op_st_T0_A0(int idx) -{ - gen_op_st_v(idx, cpu_T[0], cpu_A0); -} - -static inline void gen_op_st_T1_A0(int idx) -{ - gen_op_st_v(idx, cpu_T[1], cpu_A0); -} - static inline void gen_jmp_im(target_ulong pc) { tcg_gen_movi_tl(cpu_tmp0, pc); - tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, eip)); + gen_op_jmp_v(cpu_tmp0); } static inline void gen_string_movl_A0_ESI(DisasContext *s) @@ -684,17 +503,18 @@ static inline void gen_string_movl_A0_ESI(DisasContext *s) int override; override = s->override; + switch (s->aflag) { #ifdef TARGET_X86_64 - if (s->aflag == 2) { + case MO_64: if (override >= 0) { gen_op_movq_A0_seg(override); gen_op_addq_A0_reg_sN(0, R_ESI); } else { gen_op_movq_A0_reg(R_ESI); } - } else + break; #endif - if (s->aflag) { + case MO_32: /* 32 bit address */ if (s->addseg && override < 0) override = R_DS; @@ -704,54 +524,61 @@ static inline void gen_string_movl_A0_ESI(DisasContext *s) } else { gen_op_movl_A0_reg(R_ESI); } - } else { + break; + case MO_16: /* 16 address, always override */ if (override < 0) override = R_DS; - gen_op_movl_A0_reg(R_ESI); - gen_op_andl_A0_ffff(); + tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_ESI]); gen_op_addl_A0_seg(s, override); + break; + default: + tcg_abort(); } } static inline void gen_string_movl_A0_EDI(DisasContext *s) { + switch (s->aflag) { #ifdef TARGET_X86_64 - if (s->aflag == 2) { + case MO_64: gen_op_movq_A0_reg(R_EDI); - } else + break; #endif - if (s->aflag) { + case MO_32: if (s->addseg) { gen_op_movl_A0_seg(R_ES); gen_op_addl_A0_reg_sN(0, R_EDI); } else { gen_op_movl_A0_reg(R_EDI); } - } else { - gen_op_movl_A0_reg(R_EDI); - gen_op_andl_A0_ffff(); + break; + case MO_16: + tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_EDI]); gen_op_addl_A0_seg(s, R_ES); + break; + default: + tcg_abort(); } } -static inline void gen_op_movl_T0_Dshift(int ot) +static inline void gen_op_movl_T0_Dshift(TCGMemOp ot) { tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, df)); tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot); }; -static TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign) +static TCGv gen_ext_tl(TCGv dst, TCGv src, TCGMemOp size, bool sign) { switch (size) { - case OT_BYTE: + case MO_8: if (sign) { tcg_gen_ext8s_tl(dst, src); } else { tcg_gen_ext8u_tl(dst, src); } return dst; - case OT_WORD: + case MO_16: if (sign) { tcg_gen_ext16s_tl(dst, src); } else { @@ -759,7 +586,7 @@ static TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign) } return dst; #ifdef TARGET_X86_64 - case OT_LONG: + case MO_32: if (sign) { tcg_gen_ext32s_tl(dst, src); } else { @@ -772,61 +599,65 @@ static TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign) } } -static void gen_extu(int ot, TCGv reg) +static void gen_extu(TCGMemOp ot, TCGv reg) { gen_ext_tl(reg, reg, ot, false); } -static void gen_exts(int ot, TCGv reg) +static void gen_exts(TCGMemOp ot, TCGv reg) { gen_ext_tl(reg, reg, ot, true); } -static inline void gen_op_jnz_ecx(int size, int label1) +static inline void gen_op_jnz_ecx(TCGMemOp size, int label1) { tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]); - gen_extu(size + 1, cpu_tmp0); + gen_extu(size, cpu_tmp0); tcg_gen_brcondi_tl(TCG_COND_NE, cpu_tmp0, 0, label1); } -static inline void gen_op_jz_ecx(int size, int label1) +static inline void gen_op_jz_ecx(TCGMemOp size, int label1) { tcg_gen_mov_tl(cpu_tmp0, cpu_regs[R_ECX]); - gen_extu(size + 1, cpu_tmp0); + gen_extu(size, cpu_tmp0); tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, label1); } -static void gen_helper_in_func(int ot, TCGv v, TCGv_i32 n) +static void gen_helper_in_func(TCGMemOp ot, TCGv v, TCGv_i32 n) { switch (ot) { - case OT_BYTE: + case MO_8: gen_helper_inb(v, n); break; - case OT_WORD: + case MO_16: gen_helper_inw(v, n); break; - case OT_LONG: + case MO_32: gen_helper_inl(v, n); break; + default: + tcg_abort(); } } -static void gen_helper_out_func(int ot, TCGv_i32 v, TCGv_i32 n) +static void gen_helper_out_func(TCGMemOp ot, TCGv_i32 v, TCGv_i32 n) { switch (ot) { - case OT_BYTE: + case MO_8: gen_helper_outb(v, n); break; - case OT_WORD: + case MO_16: gen_helper_outw(v, n); break; - case OT_LONG: + case MO_32: gen_helper_outl(v, n); break; + default: + tcg_abort(); } } -static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip, +static void gen_check_io(DisasContext *s, TCGMemOp ot, target_ulong cur_eip, uint32_t svm_flags) { int state_saved; @@ -839,15 +670,17 @@ static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip, state_saved = 1; tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); switch (ot) { - case OT_BYTE: + case MO_8: gen_helper_check_iob(cpu_env, cpu_tmp2_i32); break; - case OT_WORD: + case MO_16: gen_helper_check_iow(cpu_env, cpu_tmp2_i32); break; - case OT_LONG: + case MO_32: gen_helper_check_iol(cpu_env, cpu_tmp2_i32); break; + default: + tcg_abort(); } } if(s->flags & HF_SVMI_MASK) { @@ -864,12 +697,12 @@ static void gen_check_io(DisasContext *s, int ot, target_ulong cur_eip, } } -static inline void gen_movs(DisasContext *s, int ot) +static inline void gen_movs(DisasContext *s, TCGMemOp ot) { gen_string_movl_A0_ESI(s); - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); gen_string_movl_A0_EDI(s); - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); gen_op_movl_T0_Dshift(ot); gen_op_add_reg_T0(s->aflag, R_ESI); gen_op_add_reg_T0(s->aflag, R_EDI); @@ -1058,7 +891,7 @@ static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg) return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 }; default: { - int size = (s->cc_op - CC_OP_ADDB) & 3; + TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3; TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true); return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 }; } @@ -1099,7 +932,7 @@ static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 }; default: { - int size = (s->cc_op - CC_OP_ADDB) & 3; + TCGMemOp size = (s->cc_op - CC_OP_ADDB) & 3; TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false); return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 }; } @@ -1110,7 +943,8 @@ static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg) value 'b'. In the fast case, T0 is guaranted not to be used. */ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg) { - int inv, jcc_op, size, cond; + int inv, jcc_op, cond; + TCGMemOp size; CCPrepare cc; TCGv t0; @@ -1290,37 +1124,37 @@ static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip) return l2; } -static inline void gen_stos(DisasContext *s, int ot) +static inline void gen_stos(DisasContext *s, TCGMemOp ot) { - gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); + gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX); gen_string_movl_A0_EDI(s); - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); gen_op_movl_T0_Dshift(ot); gen_op_add_reg_T0(s->aflag, R_EDI); } -static inline void gen_lods(DisasContext *s, int ot) +static inline void gen_lods(DisasContext *s, TCGMemOp ot) { gen_string_movl_A0_ESI(s); - gen_op_ld_T0_A0(ot + s->mem_index); - gen_op_mov_reg_T0(ot, R_EAX); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); + gen_op_mov_reg_v(ot, R_EAX, cpu_T[0]); gen_op_movl_T0_Dshift(ot); gen_op_add_reg_T0(s->aflag, R_ESI); } -static inline void gen_scas(DisasContext *s, int ot) +static inline void gen_scas(DisasContext *s, TCGMemOp ot) { gen_string_movl_A0_EDI(s); - gen_op_ld_T1_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[1], cpu_A0); gen_op(s, OP_CMPL, ot, R_EAX); gen_op_movl_T0_Dshift(ot); gen_op_add_reg_T0(s->aflag, R_EDI); } -static inline void gen_cmps(DisasContext *s, int ot) +static inline void gen_cmps(DisasContext *s, TCGMemOp ot) { gen_string_movl_A0_EDI(s); - gen_op_ld_T1_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[1], cpu_A0); gen_string_movl_A0_ESI(s); gen_op(s, OP_CMPL, ot, OR_TMP0); gen_op_movl_T0_Dshift(ot); @@ -1328,35 +1162,33 @@ static inline void gen_cmps(DisasContext *s, int ot) gen_op_add_reg_T0(s->aflag, R_EDI); } -static inline void gen_ins(DisasContext *s, int ot) +static inline void gen_ins(DisasContext *s, TCGMemOp ot) { if (use_icount) gen_io_start(); gen_string_movl_A0_EDI(s); /* Note: we must do this dummy write first to be restartable in case of page fault. */ - gen_op_movl_T0_0(); - gen_op_st_T0_A0(ot + s->mem_index); - gen_op_mov_TN_reg(OT_WORD, 1, R_EDX); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]); + tcg_gen_movi_tl(cpu_T[0], 0); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); + tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]); tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32); - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); gen_op_movl_T0_Dshift(ot); gen_op_add_reg_T0(s->aflag, R_EDI); if (use_icount) gen_io_end(); } -static inline void gen_outs(DisasContext *s, int ot) +static inline void gen_outs(DisasContext *s, TCGMemOp ot) { if (use_icount) gen_io_start(); gen_string_movl_A0_ESI(s); - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); - gen_op_mov_TN_reg(OT_WORD, 1, R_EDX); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[1]); + tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]); tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]); gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32); @@ -1370,7 +1202,7 @@ static inline void gen_outs(DisasContext *s, int ot) /* same method as Valgrind : we generate jumps to current or next instruction */ #define GEN_REPZ(op) \ -static inline void gen_repz_ ## op(DisasContext *s, int ot, \ +static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \ target_ulong cur_eip, target_ulong next_eip) \ { \ int l2;\ @@ -1386,7 +1218,7 @@ static inline void gen_repz_ ## op(DisasContext *s, int ot, \ } #define GEN_REPZ2(op) \ -static inline void gen_repz_ ## op(DisasContext *s, int ot, \ +static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \ target_ulong cur_eip, \ target_ulong next_eip, \ int nz) \ @@ -1468,22 +1300,19 @@ static void gen_helper_fp_arith_STN_ST0(int op, int opreg) } /* if d == OR_TMP0, it means memory operand (address in A0) */ -static void gen_op(DisasContext *s1, int op, int ot, int d) +static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d) { if (d != OR_TMP0) { - gen_op_mov_TN_reg(ot, 0, d); + gen_op_mov_v_reg(ot, cpu_T[0], d); } else { - gen_op_ld_T0_A0(ot + s1->mem_index); + gen_op_ld_v(s1, ot, cpu_T[0], cpu_A0); } switch(op) { case OP_ADCL: gen_compute_eflags_c(s1, cpu_tmp4); tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4); - if (d != OR_TMP0) - gen_op_mov_reg_T0(ot, d); - else - gen_op_st_T0_A0(ot + s1->mem_index); + gen_op_st_rm_T0_A0(s1, ot, d); gen_op_update3_cc(cpu_tmp4); set_cc_op(s1, CC_OP_ADCB + ot); break; @@ -1491,57 +1320,39 @@ static void gen_op(DisasContext *s1, int op, int ot, int d) gen_compute_eflags_c(s1, cpu_tmp4); tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4); - if (d != OR_TMP0) - gen_op_mov_reg_T0(ot, d); - else - gen_op_st_T0_A0(ot + s1->mem_index); + gen_op_st_rm_T0_A0(s1, ot, d); gen_op_update3_cc(cpu_tmp4); set_cc_op(s1, CC_OP_SBBB + ot); break; case OP_ADDL: - gen_op_addl_T0_T1(); - if (d != OR_TMP0) - gen_op_mov_reg_T0(ot, d); - else - gen_op_st_T0_A0(ot + s1->mem_index); + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + gen_op_st_rm_T0_A0(s1, ot, d); gen_op_update2_cc(); set_cc_op(s1, CC_OP_ADDB + ot); break; case OP_SUBL: tcg_gen_mov_tl(cpu_cc_srcT, cpu_T[0]); tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - if (d != OR_TMP0) - gen_op_mov_reg_T0(ot, d); - else - gen_op_st_T0_A0(ot + s1->mem_index); + gen_op_st_rm_T0_A0(s1, ot, d); gen_op_update2_cc(); set_cc_op(s1, CC_OP_SUBB + ot); break; default: case OP_ANDL: tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - if (d != OR_TMP0) - gen_op_mov_reg_T0(ot, d); - else - gen_op_st_T0_A0(ot + s1->mem_index); + gen_op_st_rm_T0_A0(s1, ot, d); gen_op_update1_cc(); set_cc_op(s1, CC_OP_LOGICB + ot); break; case OP_ORL: tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - if (d != OR_TMP0) - gen_op_mov_reg_T0(ot, d); - else - gen_op_st_T0_A0(ot + s1->mem_index); + gen_op_st_rm_T0_A0(s1, ot, d); gen_op_update1_cc(); set_cc_op(s1, CC_OP_LOGICB + ot); break; case OP_XORL: tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - if (d != OR_TMP0) - gen_op_mov_reg_T0(ot, d); - else - gen_op_st_T0_A0(ot + s1->mem_index); + gen_op_st_rm_T0_A0(s1, ot, d); gen_op_update1_cc(); set_cc_op(s1, CC_OP_LOGICB + ot); break; @@ -1555,12 +1366,13 @@ static void gen_op(DisasContext *s1, int op, int ot, int d) } /* if d == OR_TMP0, it means memory operand (address in A0) */ -static void gen_inc(DisasContext *s1, int ot, int d, int c) +static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c) { - if (d != OR_TMP0) - gen_op_mov_TN_reg(ot, 0, d); - else - gen_op_ld_T0_A0(ot + s1->mem_index); + if (d != OR_TMP0) { + gen_op_mov_v_reg(ot, cpu_T[0], d); + } else { + gen_op_ld_v(s1, ot, cpu_T[0], cpu_A0); + } gen_compute_eflags_c(s1, cpu_cc_src); if (c > 0) { tcg_gen_addi_tl(cpu_T[0], cpu_T[0], 1); @@ -1569,15 +1381,12 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c) tcg_gen_addi_tl(cpu_T[0], cpu_T[0], -1); set_cc_op(s1, CC_OP_DECB + ot); } - if (d != OR_TMP0) - gen_op_mov_reg_T0(ot, d); - else - gen_op_st_T0_A0(ot + s1->mem_index); + gen_op_st_rm_T0_A0(s1, ot, d); tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); } -static void gen_shift_flags(DisasContext *s, int ot, TCGv result, TCGv shm1, - TCGv count, bool is_right) +static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result, + TCGv shm1, TCGv count, bool is_right) { TCGv_i32 z32, s32, oldop; TCGv z_tl; @@ -1621,16 +1430,16 @@ static void gen_shift_flags(DisasContext *s, int ot, TCGv result, TCGv shm1, set_cc_op(s, CC_OP_DYNAMIC); } -static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, +static void gen_shift_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right, int is_arith) { - target_ulong mask = (ot == OT_QUAD ? 0x3f : 0x1f); + target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f); /* load */ if (op1 == OR_TMP0) { - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_TN_reg(ot, 0, op1); + gen_op_mov_v_reg(ot, cpu_T[0], op1); } tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask); @@ -1652,25 +1461,21 @@ static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, } /* store */ - if (op1 == OR_TMP0) { - gen_op_st_T0_A0(ot + s->mem_index); - } else { - gen_op_mov_reg_T0(ot, op1); - } + gen_op_st_rm_T0_A0(s, ot, op1); gen_shift_flags(s, ot, cpu_T[0], cpu_tmp0, cpu_T[1], is_right); } -static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2, +static void gen_shift_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2, int is_right, int is_arith) { - int mask = (ot == OT_QUAD ? 0x3f : 0x1f); + int mask = (ot == MO_64 ? 0x3f : 0x1f); /* load */ if (op1 == OR_TMP0) - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); else - gen_op_mov_TN_reg(ot, 0, op1); + gen_op_mov_v_reg(ot, cpu_T[0], op1); op2 &= mask; if (op2 != 0) { @@ -1691,11 +1496,8 @@ static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2, } /* store */ - if (op1 == OR_TMP0) - gen_op_st_T0_A0(ot + s->mem_index); - else - gen_op_mov_reg_T0(ot, op1); - + gen_op_st_rm_T0_A0(s, ot, op1); + /* update eflags if non zero shift */ if (op2 != 0) { tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4); @@ -1712,33 +1514,33 @@ static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2) tcg_gen_shri_tl(ret, arg1, -arg2); } -static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, int is_right) +static void gen_rot_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right) { - target_ulong mask = (ot == OT_QUAD ? 0x3f : 0x1f); + target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f); TCGv_i32 t0, t1; /* load */ if (op1 == OR_TMP0) { - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_TN_reg(ot, 0, op1); + gen_op_mov_v_reg(ot, cpu_T[0], op1); } tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask); switch (ot) { - case OT_BYTE: + case MO_8: /* Replicate the 8-bit input so that a 32-bit rotate works. */ tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]); tcg_gen_muli_tl(cpu_T[0], cpu_T[0], 0x01010101); goto do_long; - case OT_WORD: + case MO_16: /* Replicate the 16-bit input so that a 32-bit rotate works. */ tcg_gen_deposit_tl(cpu_T[0], cpu_T[0], cpu_T[0], 16, 16); goto do_long; do_long: #ifdef TARGET_X86_64 - case OT_LONG: + case MO_32: tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]); if (is_right) { @@ -1759,11 +1561,7 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, int is_right) } /* store */ - if (op1 == OR_TMP0) { - gen_op_st_T0_A0(ot + s->mem_index); - } else { - gen_op_mov_reg_T0(ot, op1); - } + gen_op_st_rm_T0_A0(s, ot, op1); /* We'll need the flags computed into CC_SRC. */ gen_compute_eflags(s); @@ -1801,24 +1599,24 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, int is_right) set_cc_op(s, CC_OP_DYNAMIC); } -static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2, +static void gen_rot_rm_im(DisasContext *s, TCGMemOp ot, int op1, int op2, int is_right) { - int mask = (ot == OT_QUAD ? 0x3f : 0x1f); + int mask = (ot == MO_64 ? 0x3f : 0x1f); int shift; /* load */ if (op1 == OR_TMP0) { - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_TN_reg(ot, 0, op1); + gen_op_mov_v_reg(ot, cpu_T[0], op1); } op2 &= mask; if (op2 != 0) { switch (ot) { #ifdef TARGET_X86_64 - case OT_LONG: + case MO_32: tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); if (is_right) { tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, op2); @@ -1835,10 +1633,10 @@ static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2, tcg_gen_rotli_tl(cpu_T[0], cpu_T[0], op2); } break; - case OT_BYTE: + case MO_8: mask = 7; goto do_shifts; - case OT_WORD: + case MO_16: mask = 15; do_shifts: shift = op2 & mask; @@ -1854,11 +1652,7 @@ static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2, } /* store */ - if (op1 == OR_TMP0) { - gen_op_st_T0_A0(ot + s->mem_index); - } else { - gen_op_mov_reg_T0(ot, op1); - } + gen_op_st_rm_T0_A0(s, ot, op1); if (op2 != 0) { /* Compute the flags into CC_SRC. */ @@ -1883,7 +1677,7 @@ static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2, } /* XXX: add faster immediate = 1 case */ -static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, +static void gen_rotc_rm_T1(DisasContext *s, TCGMemOp ot, int op1, int is_right) { gen_compute_eflags(s); @@ -1891,71 +1685,72 @@ static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, /* load */ if (op1 == OR_TMP0) - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); else - gen_op_mov_TN_reg(ot, 0, op1); + gen_op_mov_v_reg(ot, cpu_T[0], op1); if (is_right) { switch (ot) { - case OT_BYTE: + case MO_8: gen_helper_rcrb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); break; - case OT_WORD: + case MO_16: gen_helper_rcrw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); break; - case OT_LONG: + case MO_32: gen_helper_rcrl(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); break; #ifdef TARGET_X86_64 - case OT_QUAD: + case MO_64: gen_helper_rcrq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); break; #endif + default: + tcg_abort(); } } else { switch (ot) { - case OT_BYTE: + case MO_8: gen_helper_rclb(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); break; - case OT_WORD: + case MO_16: gen_helper_rclw(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); break; - case OT_LONG: + case MO_32: gen_helper_rcll(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); break; #ifdef TARGET_X86_64 - case OT_QUAD: + case MO_64: gen_helper_rclq(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); break; #endif + default: + tcg_abort(); } } /* store */ - if (op1 == OR_TMP0) - gen_op_st_T0_A0(ot + s->mem_index); - else - gen_op_mov_reg_T0(ot, op1); + gen_op_st_rm_T0_A0(s, ot, op1); } /* XXX: add faster immediate case */ -static void gen_shiftd_rm_T1(DisasContext *s, int ot, int op1, +static void gen_shiftd_rm_T1(DisasContext *s, TCGMemOp ot, int op1, bool is_right, TCGv count_in) { - target_ulong mask = (ot == OT_QUAD ? 63 : 31); + target_ulong mask = (ot == MO_64 ? 63 : 31); TCGv count; /* load */ if (op1 == OR_TMP0) { - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_TN_reg(ot, 0, op1); + gen_op_mov_v_reg(ot, cpu_T[0], op1); } count = tcg_temp_new(); tcg_gen_andi_tl(count, count_in, mask); switch (ot) { - case OT_WORD: + case MO_16: /* Note: we implement the Intel behaviour for shift count > 16. This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A portion by constructing it as a 32-bit value. */ @@ -1968,7 +1763,7 @@ static void gen_shiftd_rm_T1(DisasContext *s, int ot, int op1, } /* FALLTHRU */ #ifdef TARGET_X86_64 - case OT_LONG: + case MO_32: /* Concatenate the two 32-bit values and use a 64-bit shift. */ tcg_gen_subi_tl(cpu_tmp0, count, 1); if (is_right) { @@ -1994,7 +1789,7 @@ static void gen_shiftd_rm_T1(DisasContext *s, int ot, int op1, tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_tmp4); } else { tcg_gen_shl_tl(cpu_tmp0, cpu_T[0], cpu_tmp0); - if (ot == OT_WORD) { + if (ot == MO_16) { /* Only needed if count > 16, for Intel behaviour. */ tcg_gen_subfi_tl(cpu_tmp4, 33, count); tcg_gen_shr_tl(cpu_tmp4, cpu_T[1], cpu_tmp4); @@ -2013,20 +1808,16 @@ static void gen_shiftd_rm_T1(DisasContext *s, int ot, int op1, } /* store */ - if (op1 == OR_TMP0) { - gen_op_st_T0_A0(ot + s->mem_index); - } else { - gen_op_mov_reg_T0(ot, op1); - } + gen_op_st_rm_T0_A0(s, ot, op1); gen_shift_flags(s, ot, cpu_T[0], cpu_tmp0, count, is_right); tcg_temp_free(count); } -static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) +static void gen_shift(DisasContext *s1, int op, TCGMemOp ot, int d, int s) { if (s != OR_TMP1) - gen_op_mov_TN_reg(ot, 1, s); + gen_op_mov_v_reg(ot, cpu_T[1], s); switch(op) { case OP_ROL: gen_rot_rm_T1(s1, ot, d, 0); @@ -2053,7 +1844,7 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s) } } -static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c) +static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c) { switch(op) { case OP_ROL: @@ -2074,21 +1865,19 @@ static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c) break; default: /* currently not optimized */ - gen_op_movl_T1_im(c); + tcg_gen_movi_tl(cpu_T[1], c); gen_shift(s1, op, ot, d, OR_TMP1); break; } } -static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, - int *reg_ptr, int *offset_ptr) +static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm) { target_long disp; int havesib; int base; int index; int scale; - int opreg; int mod, rm, code, override, must_add_seg; TCGv sum; @@ -2099,7 +1888,9 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, mod = (modrm >> 6) & 3; rm = modrm & 7; - if (s->aflag) { + switch (s->aflag) { + case MO_64: + case MO_32: havesib = 0; base = rm; index = -1; @@ -2179,26 +1970,28 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[override].base)); if (CODE64(s)) { - if (s->aflag != 2) { + if (s->aflag == MO_32) { tcg_gen_ext32u_tl(cpu_A0, cpu_A0); } tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); - goto done; + return; } tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); } - if (s->aflag != 2) { + if (s->aflag == MO_32) { tcg_gen_ext32u_tl(cpu_A0, cpu_A0); } - } else { + break; + + case MO_16: switch (mod) { case 0: if (rm == 6) { disp = cpu_lduw_code(env, s->pc); s->pc += 2; - gen_op_movl_A0_im(disp); + tcg_gen_movi_tl(cpu_A0, disp); rm = 0; /* avoid SS override */ goto no_rm; } else { @@ -2210,61 +2003,57 @@ static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm, break; default: case 2: - disp = cpu_lduw_code(env, s->pc); + disp = (int16_t)cpu_lduw_code(env, s->pc); s->pc += 2; break; } - switch(rm) { + + sum = cpu_A0; + switch (rm) { case 0: - gen_op_movl_A0_reg(R_EBX); - gen_op_addl_A0_reg_sN(0, R_ESI); + tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBX], cpu_regs[R_ESI]); break; case 1: - gen_op_movl_A0_reg(R_EBX); - gen_op_addl_A0_reg_sN(0, R_EDI); + tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBX], cpu_regs[R_EDI]); break; case 2: - gen_op_movl_A0_reg(R_EBP); - gen_op_addl_A0_reg_sN(0, R_ESI); + tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_ESI]); break; case 3: - gen_op_movl_A0_reg(R_EBP); - gen_op_addl_A0_reg_sN(0, R_EDI); + tcg_gen_add_tl(cpu_A0, cpu_regs[R_EBP], cpu_regs[R_EDI]); break; case 4: - gen_op_movl_A0_reg(R_ESI); + sum = cpu_regs[R_ESI]; break; case 5: - gen_op_movl_A0_reg(R_EDI); + sum = cpu_regs[R_EDI]; break; case 6: - gen_op_movl_A0_reg(R_EBP); + sum = cpu_regs[R_EBP]; break; default: case 7: - gen_op_movl_A0_reg(R_EBX); + sum = cpu_regs[R_EBX]; break; } - if (disp != 0) - gen_op_addl_A0_im(disp); - gen_op_andl_A0_ffff(); + tcg_gen_addi_tl(cpu_A0, sum, disp); + tcg_gen_ext16u_tl(cpu_A0, cpu_A0); no_rm: if (must_add_seg) { if (override < 0) { - if (rm == 2 || rm == 3 || rm == 6) + if (rm == 2 || rm == 3 || rm == 6) { override = R_SS; - else + } else { override = R_DS; + } } gen_op_addl_A0_seg(s, override); } - } + break; - done: - opreg = OR_A0; - disp = 0; - *reg_ptr = opreg; - *offset_ptr = disp; + default: + tcg_abort(); + } } static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) @@ -2276,8 +2065,9 @@ static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) return; rm = modrm & 7; - if (s->aflag) { - + switch (s->aflag) { + case MO_64: + case MO_32: base = rm; if (base == 4) { @@ -2299,7 +2089,9 @@ static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) s->pc += 4; break; } - } else { + break; + + case MO_16: switch (mod) { case 0: if (rm == 6) { @@ -2314,6 +2106,10 @@ static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm) s->pc += 2; break; } + break; + + default: + tcg_abort(); } } @@ -2342,64 +2138,69 @@ static void gen_add_A0_ds_seg(DisasContext *s) /* generate modrm memory load or store of 'reg'. TMP0 is used if reg == OR_TMP0 */ static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm, - int ot, int reg, int is_store) + TCGMemOp ot, int reg, int is_store) { - int mod, rm, opreg, disp; + int mod, rm; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); if (mod == 3) { if (is_store) { if (reg != OR_TMP0) - gen_op_mov_TN_reg(ot, 0, reg); - gen_op_mov_reg_T0(ot, rm); + gen_op_mov_v_reg(ot, cpu_T[0], reg); + gen_op_mov_reg_v(ot, rm, cpu_T[0]); } else { - gen_op_mov_TN_reg(ot, 0, rm); + gen_op_mov_v_reg(ot, cpu_T[0], rm); if (reg != OR_TMP0) - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); } } else { - gen_lea_modrm(env, s, modrm, &opreg, &disp); + gen_lea_modrm(env, s, modrm); if (is_store) { if (reg != OR_TMP0) - gen_op_mov_TN_reg(ot, 0, reg); - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_mov_v_reg(ot, cpu_T[0], reg); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); if (reg != OR_TMP0) - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); } } } -static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, int ot) +static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot) { uint32_t ret; - switch(ot) { - case OT_BYTE: + switch (ot) { + case MO_8: ret = cpu_ldub_code(env, s->pc); s->pc++; break; - case OT_WORD: + case MO_16: ret = cpu_lduw_code(env, s->pc); s->pc += 2; break; - default: - case OT_LONG: + case MO_32: +#ifdef TARGET_X86_64 + case MO_64: +#endif ret = cpu_ldl_code(env, s->pc); s->pc += 4; break; + default: + tcg_abort(); } return ret; } -static inline int insn_const_size(unsigned int ot) +static inline int insn_const_size(TCGMemOp ot) { - if (ot <= OT_LONG) + if (ot <= MO_32) { return 1 << ot; - else + } else { return 4; + } } static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) @@ -2452,7 +2253,7 @@ static inline void gen_jcc(DisasContext *s, int b, } } -static void gen_cmovcc1(CPUX86State *env, DisasContext *s, int ot, int b, +static void gen_cmovcc1(CPUX86State *env, DisasContext *s, TCGMemOp ot, int b, int modrm, int reg) { CCPrepare cc; @@ -2471,7 +2272,7 @@ static void gen_cmovcc1(CPUX86State *env, DisasContext *s, int ot, int b, tcg_gen_movcond_tl(cc.cond, cpu_T[0], cc.reg, cc.reg2, cpu_T[0], cpu_regs[reg]); - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); if (cc.mask != -1) { tcg_temp_free(cc.reg); @@ -2548,135 +2349,80 @@ static inline void gen_stack_update(DisasContext *s, int addend) { #ifdef TARGET_X86_64 if (CODE64(s)) { - gen_op_add_reg_im(2, R_ESP, addend); + gen_op_add_reg_im(MO_64, R_ESP, addend); } else #endif if (s->ss32) { - gen_op_add_reg_im(1, R_ESP, addend); + gen_op_add_reg_im(MO_32, R_ESP, addend); } else { - gen_op_add_reg_im(0, R_ESP, addend); + gen_op_add_reg_im(MO_16, R_ESP, addend); } } -/* generate a push. It depends on ss32, addseg and dflag */ -static void gen_push_T0(DisasContext *s) +/* Generate a push. It depends on ss32, addseg and dflag. */ +static void gen_push_v(DisasContext *s, TCGv val) { -#ifdef TARGET_X86_64 - if (CODE64(s)) { - gen_op_movq_A0_reg(R_ESP); - if (s->dflag) { - gen_op_addq_A0_im(-8); - gen_op_st_T0_A0(OT_QUAD + s->mem_index); - } else { - gen_op_addq_A0_im(-2); - gen_op_st_T0_A0(OT_WORD + s->mem_index); - } - gen_op_mov_reg_A0(2, R_ESP); - } else -#endif - { - gen_op_movl_A0_reg(R_ESP); - if (!s->dflag) - gen_op_addl_A0_im(-2); - else - gen_op_addl_A0_im(-4); - if (s->ss32) { - if (s->addseg) { - tcg_gen_mov_tl(cpu_T[1], cpu_A0); - gen_op_addl_A0_seg(s, R_SS); - } - } else { - gen_op_andl_A0_ffff(); - tcg_gen_mov_tl(cpu_T[1], cpu_A0); - gen_op_addl_A0_seg(s, R_SS); - } - gen_op_st_T0_A0(s->dflag + 1 + s->mem_index); - if (s->ss32 && !s->addseg) - gen_op_mov_reg_A0(1, R_ESP); - else - gen_op_mov_reg_T1(s->ss32 + 1, R_ESP); - } -} + TCGMemOp a_ot, d_ot = mo_pushpop(s, s->dflag); + int size = 1 << d_ot; + TCGv new_esp = cpu_A0; + + tcg_gen_subi_tl(cpu_A0, cpu_regs[R_ESP], size); -/* generate a push. It depends on ss32, addseg and dflag */ -/* slower version for T1, only used for call Ev */ -static void gen_push_T1(DisasContext *s) -{ -#ifdef TARGET_X86_64 if (CODE64(s)) { - gen_op_movq_A0_reg(R_ESP); - if (s->dflag) { - gen_op_addq_A0_im(-8); - gen_op_st_T1_A0(OT_QUAD + s->mem_index); - } else { - gen_op_addq_A0_im(-2); - gen_op_st_T0_A0(OT_WORD + s->mem_index); - } - gen_op_mov_reg_A0(2, R_ESP); - } else -#endif - { - gen_op_movl_A0_reg(R_ESP); - if (!s->dflag) - gen_op_addl_A0_im(-2); - else - gen_op_addl_A0_im(-4); - if (s->ss32) { - if (s->addseg) { - gen_op_addl_A0_seg(s, R_SS); - } - } else { - gen_op_andl_A0_ffff(); + a_ot = MO_64; + } else if (s->ss32) { + a_ot = MO_32; + if (s->addseg) { + new_esp = cpu_tmp4; + tcg_gen_mov_tl(new_esp, cpu_A0); gen_op_addl_A0_seg(s, R_SS); + } else { + tcg_gen_ext32u_tl(cpu_A0, cpu_A0); } - gen_op_st_T1_A0(s->dflag + 1 + s->mem_index); - - if (s->ss32 && !s->addseg) - gen_op_mov_reg_A0(1, R_ESP); - else - gen_stack_update(s, (-2) << s->dflag); + } else { + a_ot = MO_16; + new_esp = cpu_tmp4; + tcg_gen_ext16u_tl(cpu_A0, cpu_A0); + tcg_gen_mov_tl(new_esp, cpu_A0); + gen_op_addl_A0_seg(s, R_SS); } + + gen_op_st_v(s, d_ot, val, cpu_A0); + gen_op_mov_reg_v(a_ot, R_ESP, new_esp); } /* two step pop is necessary for precise exceptions */ -static void gen_pop_T0(DisasContext *s) +static TCGMemOp gen_pop_T0(DisasContext *s) { -#ifdef TARGET_X86_64 + TCGMemOp d_ot = mo_pushpop(s, s->dflag); + TCGv addr = cpu_A0; + if (CODE64(s)) { - gen_op_movq_A0_reg(R_ESP); - gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index); - } else -#endif - { - gen_op_movl_A0_reg(R_ESP); - if (s->ss32) { - if (s->addseg) - gen_op_addl_A0_seg(s, R_SS); - } else { - gen_op_andl_A0_ffff(); - gen_op_addl_A0_seg(s, R_SS); - } - gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index); + addr = cpu_regs[R_ESP]; + } else if (!s->ss32) { + tcg_gen_ext16u_tl(cpu_A0, cpu_regs[R_ESP]); + gen_op_addl_A0_seg(s, R_SS); + } else if (s->addseg) { + tcg_gen_mov_tl(cpu_A0, cpu_regs[R_ESP]); + gen_op_addl_A0_seg(s, R_SS); + } else { + tcg_gen_ext32u_tl(cpu_A0, cpu_regs[R_ESP]); } + + gen_op_ld_v(s, d_ot, cpu_T[0], addr); + return d_ot; } -static void gen_pop_update(DisasContext *s) +static void gen_pop_update(DisasContext *s, TCGMemOp ot) { -#ifdef TARGET_X86_64 - if (CODE64(s) && s->dflag) { - gen_stack_update(s, 8); - } else -#endif - { - gen_stack_update(s, 2 << s->dflag); - } + gen_stack_update(s, 1 << ot); } static void gen_stack_A0(DisasContext *s) { gen_op_movl_A0_reg(R_ESP); if (!s->ss32) - gen_op_andl_A0_ffff(); + tcg_gen_ext16u_tl(cpu_A0, cpu_A0); tcg_gen_mov_tl(cpu_T[1], cpu_A0); if (s->addseg) gen_op_addl_A0_seg(s, R_SS); @@ -2687,18 +2433,18 @@ static void gen_pusha(DisasContext *s) { int i; gen_op_movl_A0_reg(R_ESP); - gen_op_addl_A0_im(-16 << s->dflag); + gen_op_addl_A0_im(-8 << s->dflag); if (!s->ss32) - gen_op_andl_A0_ffff(); + tcg_gen_ext16u_tl(cpu_A0, cpu_A0); tcg_gen_mov_tl(cpu_T[1], cpu_A0); if (s->addseg) gen_op_addl_A0_seg(s, R_SS); for(i = 0;i < 8; i++) { - gen_op_mov_TN_reg(OT_LONG, 0, 7 - i); - gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index); - gen_op_addl_A0_im(2 << s->dflag); + gen_op_mov_v_reg(MO_32, cpu_T[0], 7 - i); + gen_op_st_v(s, s->dflag, cpu_T[0], cpu_A0); + gen_op_addl_A0_im(1 << s->dflag); } - gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP); + gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]); } /* NOTE: wrap around in 16 bit not fully handled */ @@ -2707,73 +2453,68 @@ static void gen_popa(DisasContext *s) int i; gen_op_movl_A0_reg(R_ESP); if (!s->ss32) - gen_op_andl_A0_ffff(); + tcg_gen_ext16u_tl(cpu_A0, cpu_A0); tcg_gen_mov_tl(cpu_T[1], cpu_A0); - tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 16 << s->dflag); + tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 8 << s->dflag); if (s->addseg) gen_op_addl_A0_seg(s, R_SS); for(i = 0;i < 8; i++) { /* ESP is not reloaded */ if (i != 3) { - gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index); - gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i); + gen_op_ld_v(s, s->dflag, cpu_T[0], cpu_A0); + gen_op_mov_reg_v(s->dflag, 7 - i, cpu_T[0]); } - gen_op_addl_A0_im(2 << s->dflag); + gen_op_addl_A0_im(1 << s->dflag); } - gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP); + gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]); } static void gen_enter(DisasContext *s, int esp_addend, int level) { - int ot, opsize; + TCGMemOp ot = mo_pushpop(s, s->dflag); + int opsize = 1 << ot; level &= 0x1f; #ifdef TARGET_X86_64 if (CODE64(s)) { - ot = s->dflag ? OT_QUAD : OT_WORD; - opsize = 1 << ot; - gen_op_movl_A0_reg(R_ESP); gen_op_addq_A0_im(-opsize); tcg_gen_mov_tl(cpu_T[1], cpu_A0); /* push bp */ - gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); if (level) { /* XXX: must save state */ gen_helper_enter64_level(cpu_env, tcg_const_i32(level), - tcg_const_i32((ot == OT_QUAD)), + tcg_const_i32((ot == MO_64)), cpu_T[1]); } - gen_op_mov_reg_T1(ot, R_EBP); + gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]); tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level)); - gen_op_mov_reg_T1(OT_QUAD, R_ESP); + gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[1]); } else #endif { - ot = s->dflag + OT_WORD; - opsize = 2 << s->dflag; - gen_op_movl_A0_reg(R_ESP); gen_op_addl_A0_im(-opsize); if (!s->ss32) - gen_op_andl_A0_ffff(); + tcg_gen_ext16u_tl(cpu_A0, cpu_A0); tcg_gen_mov_tl(cpu_T[1], cpu_A0); if (s->addseg) gen_op_addl_A0_seg(s, R_SS); /* push bp */ - gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); if (level) { /* XXX: must save state */ gen_helper_enter_level(cpu_env, tcg_const_i32(level), - tcg_const_i32(s->dflag), + tcg_const_i32(s->dflag - 1), cpu_T[1]); } - gen_op_mov_reg_T1(ot, R_EBP); + gen_op_mov_reg_v(ot, R_EBP, cpu_T[1]); tcg_gen_addi_tl(cpu_T[1], cpu_T[1], -esp_addend + (-opsize * level)); - gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP); + gen_op_mov_reg_v(MO_16 + s->ss32, R_ESP, cpu_T[1]); } } @@ -2846,38 +2587,36 @@ static void gen_jmp(DisasContext *s, target_ulong eip) gen_jmp_tb(s, eip, 0); } -static inline void gen_ldq_env_A0(int idx, int offset) +static inline void gen_ldq_env_A0(DisasContext *s, int offset) { - int mem_index = (idx >> 2) - 1; - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index); + tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ); tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset); } -static inline void gen_stq_env_A0(int idx, int offset) +static inline void gen_stq_env_A0(DisasContext *s, int offset) { - int mem_index = (idx >> 2) - 1; tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index); + tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ); } -static inline void gen_ldo_env_A0(int idx, int offset) +static inline void gen_ldo_env_A0(DisasContext *s, int offset) { - int mem_index = (idx >> 2) - 1; - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, mem_index); + int mem_index = s->mem_index; + tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ); tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0))); tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8); - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_tmp0, mem_index); + tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ); tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1))); } -static inline void gen_sto_env_A0(int idx, int offset) +static inline void gen_sto_env_A0(DisasContext *s, int offset) { - int mem_index = (idx >> 2) - 1; + int mem_index = s->mem_index; tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0))); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, mem_index); + tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ); tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8); tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1))); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_tmp0, mem_index); + tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ); } static inline void gen_op_movo(int d_offset, int s_offset) @@ -3239,12 +2978,13 @@ static const struct SSEOpHelper_eppi sse_op_table7[256] = { static void gen_sse(CPUX86State *env, DisasContext *s, int b, target_ulong pc_start, int rex_r) { - int b1, op1_offset, op2_offset, is_xmm, val, ot; - int modrm, mod, rm, reg, reg_addr, offset_addr; + int b1, op1_offset, op2_offset, is_xmm, val; + int modrm, mod, rm, reg; SSEFunc_0_epp sse_fn_epp; SSEFunc_0_eppi sse_fn_eppi; SSEFunc_0_ppi sse_fn_ppi; SSEFunc_0_eppt sse_fn_eppt; + TCGMemOp ot; b &= 0xff; if (s->prefix & PREFIX_DATA) @@ -3311,46 +3051,45 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x0e7: /* movntq */ if (mod == 3) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx)); + gen_lea_modrm(env, s, modrm); + gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); break; case 0x1e7: /* movntdq */ case 0x02b: /* movntps */ case 0x12b: /* movntps */ if (mod == 3) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); + gen_lea_modrm(env, s, modrm); + gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); break; case 0x3f0: /* lddqu */ if (mod == 3) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); + gen_lea_modrm(env, s, modrm); + gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); break; case 0x22b: /* movntss */ case 0x32b: /* movntsd */ if (mod == 3) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); if (b1 & 1) { - gen_stq_env_A0(s->mem_index, offsetof(CPUX86State, - xmm_regs[reg])); + gen_stq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_L(0))); - gen_op_st_T0_A0(OT_LONG + s->mem_index); + gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0); } break; case 0x6e: /* movd mm, ea */ #ifdef TARGET_X86_64 - if (s->dflag == 2) { - gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 0); + if (s->dflag == MO_64) { + gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0); tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); } else #endif { - gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); @@ -3359,15 +3098,15 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x16e: /* movd xmm, ea */ #ifdef TARGET_X86_64 - if (s->dflag == 2) { - gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 0); + if (s->dflag == MO_64) { + gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[reg])); gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]); } else #endif { - gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[reg])); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); @@ -3376,8 +3115,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x6f: /* movq mm, ea */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx)); + gen_lea_modrm(env, s, modrm); + gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); } else { rm = (modrm & 7); tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, @@ -3393,8 +3132,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x16f: /* movdqa xmm, ea */ case 0x26f: /* movdqu xmm, ea */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); + gen_lea_modrm(env, s, modrm); + gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { rm = (modrm & 7) | REX_B(s); gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]), @@ -3403,10 +3142,10 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x210: /* movss xmm, ea */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_ld_T0_A0(OT_LONG + s->mem_index); + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); - gen_op_movl_T0_0(); + tcg_gen_movi_tl(cpu_T[0], 0); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1))); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2))); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3))); @@ -3418,9 +3157,10 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x310: /* movsd xmm, ea */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); - gen_op_movl_T0_0(); + gen_lea_modrm(env, s, modrm); + gen_ldq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(0))); + tcg_gen_movi_tl(cpu_T[0], 0); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2))); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3))); } else { @@ -3432,8 +3172,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x012: /* movlps */ case 0x112: /* movlpd */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); + gen_lea_modrm(env, s, modrm); + gen_ldq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(0))); } else { /* movhlps */ rm = (modrm & 7) | REX_B(s); @@ -3443,8 +3184,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x212: /* movsldup */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); + gen_lea_modrm(env, s, modrm); + gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)), @@ -3459,8 +3200,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x312: /* movddup */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); + gen_lea_modrm(env, s, modrm); + gen_ldq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(0))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)), @@ -3472,8 +3214,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x016: /* movhps */ case 0x116: /* movhpd */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1))); + gen_lea_modrm(env, s, modrm); + gen_ldq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(1))); } else { /* movlhps */ rm = (modrm & 7) | REX_B(s); @@ -3483,8 +3226,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x216: /* movshdup */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldo_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); + gen_lea_modrm(env, s, modrm); + gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)), @@ -3520,36 +3263,37 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x7e: /* movd ea, mm */ #ifdef TARGET_X86_64 - if (s->dflag == 2) { + if (s->dflag == MO_64) { tcg_gen_ld_i64(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); - gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 1); + gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1); } else #endif { tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0))); - gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 1); + gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1); } break; case 0x17e: /* movd ea, xmm */ #ifdef TARGET_X86_64 - if (s->dflag == 2) { + if (s->dflag == MO_64) { tcg_gen_ld_i64(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); - gen_ldst_modrm(env, s, modrm, OT_QUAD, OR_TMP0, 1); + gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1); } else #endif { tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); - gen_ldst_modrm(env, s, modrm, OT_LONG, OR_TMP0, 1); + gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1); } break; case 0x27e: /* movq xmm, ea */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); + gen_lea_modrm(env, s, modrm); + gen_ldq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(0))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)), @@ -3559,8 +3303,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x7f: /* movq ea, mm */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,fpregs[reg].mmx)); + gen_lea_modrm(env, s, modrm); + gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); } else { rm = (modrm & 7); gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx), @@ -3574,8 +3318,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x17f: /* movdqa ea, xmm */ case 0x27f: /* movdqu ea, xmm */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_sto_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg])); + gen_lea_modrm(env, s, modrm); + gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { rm = (modrm & 7) | REX_B(s); gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]), @@ -3584,9 +3328,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x211: /* movss ea, xmm */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); - gen_op_st_T0_A0(OT_LONG + s->mem_index); + gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)), @@ -3595,8 +3339,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x311: /* movsd ea, xmm */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); + gen_lea_modrm(env, s, modrm); + gen_stq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(0))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)), @@ -3606,8 +3351,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x013: /* movlps */ case 0x113: /* movlpd */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); + gen_lea_modrm(env, s, modrm); + gen_stq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(0))); } else { goto illegal_op; } @@ -3615,8 +3361,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x017: /* movhps */ case 0x117: /* movhpd */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1))); + gen_lea_modrm(env, s, modrm); + gen_stq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(1))); } else { goto illegal_op; } @@ -3632,15 +3379,15 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, } val = cpu_ldub_code(env, s->pc++); if (is_xmm) { - gen_op_movl_T0_im(val); + tcg_gen_movi_tl(cpu_T[0], val); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0))); - gen_op_movl_T0_0(); + tcg_gen_movi_tl(cpu_T[0], 0); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1))); op1_offset = offsetof(CPUX86State,xmm_t0); } else { - gen_op_movl_T0_im(val); + tcg_gen_movi_tl(cpu_T[0], val); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0))); - gen_op_movl_T0_0(); + tcg_gen_movi_tl(cpu_T[0], 0); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1))); op1_offset = offsetof(CPUX86State,mmx_t0); } @@ -3665,24 +3412,22 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm])); gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_mov_reg_T0(OT_LONG, reg); + tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32); break; case 0x150: /* movmskpd */ rm = (modrm & 7) | REX_B(s); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm])); gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_mov_reg_T0(OT_LONG, reg); + tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32); break; case 0x02a: /* cvtpi2ps */ case 0x12a: /* cvtpi2pd */ gen_helper_enter_mmx(cpu_env); if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,mmx_t0); - gen_ldq_env_A0(s->mem_index, op2_offset); + gen_ldq_env_A0(s, op2_offset); } else { rm = (modrm & 7); op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); @@ -3702,11 +3447,11 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, break; case 0x22a: /* cvtsi2ss */ case 0x32a: /* cvtsi2sd */ - ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); op1_offset = offsetof(CPUX86State,xmm_regs[reg]); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); - if (ot == OT_LONG) { + if (ot == MO_32) { SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1]; tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32); @@ -3725,9 +3470,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x12d: /* cvtpd2pi */ gen_helper_enter_mmx(cpu_env); if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,xmm_t0); - gen_ldo_env_A0(s->mem_index, op2_offset); + gen_ldo_env_A0(s, op2_offset); } else { rm = (modrm & 7) | REX_B(s); op2_offset = offsetof(CPUX86State,xmm_regs[rm]); @@ -3754,13 +3499,13 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x32c: /* cvttsd2si */ case 0x22d: /* cvtss2si */ case 0x32d: /* cvtsd2si */ - ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); if ((b >> 8) & 1) { - gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_Q(0))); + gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.XMM_Q(0))); } else { - gen_op_ld_T0_A0(OT_LONG + s->mem_index); + gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0))); } op2_offset = offsetof(CPUX86State,xmm_t0); @@ -3769,7 +3514,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, op2_offset = offsetof(CPUX86State,xmm_regs[rm]); } tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset); - if (ot == OT_LONG) { + if (ot == MO_32) { SSEFunc_i_ep sse_fn_i_ep = sse_op_table3bi[((b >> 7) & 2) | (b & 1)]; sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0); @@ -3783,12 +3528,12 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, goto illegal_op; #endif } - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; case 0xc4: /* pinsrw */ case 0x1c4: s->rip_offset = 1; - gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); val = cpu_ldub_code(env, s->pc++); if (b1) { val &= 7; @@ -3804,7 +3549,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x1c5: if (mod != 3) goto illegal_op; - ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); val = cpu_ldub_code(env, s->pc++); if (b1) { val &= 7; @@ -3818,12 +3563,13 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val))); } reg = ((modrm >> 3) & 7) | rex_r; - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; case 0x1d6: /* movq ea, xmm */ if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_stq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); + gen_lea_modrm(env, s, modrm); + gen_stq_env_A0(s, offsetof(CPUX86State, + xmm_regs[reg].XMM_Q(0))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)), @@ -3857,9 +3603,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx)); gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0); } - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); reg = ((modrm >> 3) & 7) | rex_r; - gen_op_mov_reg_T0(OT_LONG, reg); + tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32); break; case 0x138: @@ -3889,33 +3634,32 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]); } else { op2_offset = offsetof(CPUX86State,xmm_t0); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); switch (b) { case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */ case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */ case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */ - gen_ldq_env_A0(s->mem_index, op2_offset + + gen_ldq_env_A0(s, op2_offset + offsetof(XMMReg, XMM_Q(0))); break; case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */ case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */ - tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0, - (s->mem_index >> 2) - 1); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset + offsetof(XMMReg, XMM_L(0))); break; case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */ - tcg_gen_qemu_ld16u(cpu_tmp0, cpu_A0, - (s->mem_index >> 2) - 1); + tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0, + s->mem_index, MO_LEUW); tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset + offsetof(XMMReg, XMM_W(0))); break; case 0x2a: /* movntqda */ - gen_ldo_env_A0(s->mem_index, op1_offset); + gen_ldo_env_A0(s, op1_offset); return; default: - gen_ldo_env_A0(s->mem_index, op2_offset); + gen_ldo_env_A0(s, op2_offset); } } } else { @@ -3924,8 +3668,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); } else { op2_offset = offsetof(CPUX86State,mmx_t0); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldq_env_A0(s->mem_index, op2_offset); + gen_lea_modrm(env, s, modrm); + gen_ldq_env_A0(s, op2_offset); } } if (sse_fn_epp == SSE_SPECIAL) { @@ -3957,21 +3701,20 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, goto illegal_op; } if ((b & 0xff) == 0xf0) { - ot = OT_BYTE; - } else if (s->dflag != 2) { - ot = (s->prefix & PREFIX_DATA ? OT_WORD : OT_LONG); + ot = MO_8; + } else if (s->dflag != MO_64) { + ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32); } else { - ot = OT_QUAD; + ot = MO_64; } - gen_op_mov_TN_reg(OT_LONG, 0, reg); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_helper_crc32(cpu_T[0], cpu_tmp2_i32, cpu_T[0], tcg_const_i32(8 << ot)); - ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; - gen_op_mov_reg_T0(ot, reg); + ot = mo_64_32(s->dflag); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; case 0x1f0: /* crc32 or movbe */ @@ -3988,50 +3731,20 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) { goto illegal_op; } - if (s->dflag != 2) { - ot = (s->prefix & PREFIX_DATA ? OT_WORD : OT_LONG); + if (s->dflag != MO_64) { + ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32); } else { - ot = OT_QUAD; + ot = MO_64; } - /* Load the data incoming to the bswap. Note that the TCG - implementation of bswap requires the input be zero - extended. In the case of the loads, we simply know that - gen_op_ld_v via gen_ldst_modrm does that already. */ + gen_lea_modrm(env, s, modrm); if ((b & 1) == 0) { - gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); + tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0, + s->mem_index, ot | MO_BE); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); } else { - switch (ot) { - case OT_WORD: - tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[reg]); - break; - default: - tcg_gen_ext32u_tl(cpu_T[0], cpu_regs[reg]); - break; - case OT_QUAD: - tcg_gen_mov_tl(cpu_T[0], cpu_regs[reg]); - break; - } - } - - switch (ot) { - case OT_WORD: - tcg_gen_bswap16_tl(cpu_T[0], cpu_T[0]); - break; - default: - tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]); - break; -#ifdef TARGET_X86_64 - case OT_QUAD: - tcg_gen_bswap64_tl(cpu_T[0], cpu_T[0]); - break; -#endif - } - - if ((b & 1) == 0) { - gen_op_mov_reg_T0(ot, reg); - } else { - gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); + tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0, + s->mem_index, ot | MO_BE); } break; @@ -4041,10 +3754,10 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); tcg_gen_andc_tl(cpu_T[0], cpu_regs[s->vex_v], cpu_T[0]); - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); gen_op_update1_cc(); set_cc_op(s, CC_OP_LOGICB + ot); break; @@ -4055,7 +3768,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); { TCGv bound, zero; @@ -4065,7 +3778,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]); tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_A0); - bound = tcg_const_tl(ot == OT_QUAD ? 63 : 31); + bound = tcg_const_tl(ot == MO_64 ? 63 : 31); zero = tcg_const_tl(0); tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T[0], cpu_A0, bound, cpu_T[0], zero); @@ -4083,7 +3796,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_subi_tl(cpu_T[1], cpu_T[1], 1); tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); gen_op_update1_cc(); set_cc_op(s, CC_OP_LOGICB + ot); } @@ -4095,11 +3808,11 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); tcg_gen_ext8u_tl(cpu_T[1], cpu_regs[s->vex_v]); { - TCGv bound = tcg_const_tl(ot == OT_QUAD ? 63 : 31); + TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31); /* Note that since we're using BMILG (in order to get O cleared) we need to store the inverse into C. */ tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src, @@ -4111,7 +3824,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_movi_tl(cpu_A0, -1); tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T[1]); tcg_gen_andc_tl(cpu_T[0], cpu_T[0], cpu_A0); - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); gen_op_update1_cc(); set_cc_op(s, CC_OP_BMILGB + ot); break; @@ -4122,7 +3835,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); switch (ot) { default: @@ -4134,7 +3847,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32); break; #ifdef TARGET_X86_64 - case OT_QUAD: + case MO_64: tcg_gen_mulu2_i64(cpu_regs[s->vex_v], cpu_regs[reg], cpu_T[0], cpu_regs[R_EDX]); break; @@ -4148,11 +3861,11 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); /* Note that by zero-extending the mask operand, we automatically handle zero-extending the result. */ - if (s->dflag == 2) { + if (ot == MO_64) { tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]); } else { tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]); @@ -4166,11 +3879,11 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); /* Note that by zero-extending the mask operand, we automatically handle zero-extending the result. */ - if (s->dflag == 2) { + if (ot == MO_64) { tcg_gen_mov_tl(cpu_T[1], cpu_regs[s->vex_v]); } else { tcg_gen_ext32u_tl(cpu_T[1], cpu_regs[s->vex_v]); @@ -4186,7 +3899,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, TCGv carry_in, carry_out, zero; int end_op; - ot = (s->dflag == 2 ? OT_QUAD : OT_LONG); + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); /* Re-use the carry-out from a previous round. */ @@ -4230,7 +3943,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, switch (ot) { #ifdef TARGET_X86_64 - case OT_LONG: + case MO_32: /* If we know TL is 64-bit, and we want a 32-bit result, just do everything in 64-bit arithmetic. */ tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]); @@ -4265,9 +3978,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = (s->dflag == 2 ? OT_QUAD : OT_LONG); + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); - if (ot == OT_QUAD) { + if (ot == MO_64) { tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 63); } else { tcg_gen_andi_tl(cpu_T[1], cpu_regs[s->vex_v], 31); @@ -4275,17 +3988,17 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, if (b == 0x1f7) { tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]); } else if (b == 0x2f7) { - if (ot != OT_QUAD) { + if (ot != MO_64) { tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); } tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]); } else { - if (ot != OT_QUAD) { + if (ot != MO_64) { tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); } tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]); } - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; case 0x0f3: @@ -4297,14 +4010,14 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); switch (reg & 7) { case 1: /* blsr By,Ey */ tcg_gen_neg_tl(cpu_T[1], cpu_T[0]); tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - gen_op_mov_reg_T0(ot, s->vex_v); + gen_op_mov_reg_v(ot, s->vex_v, cpu_T[0]); gen_op_update2_cc(); set_cc_op(s, CC_OP_BMILGB + ot); break; @@ -4354,52 +4067,55 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, goto illegal_op; if (sse_fn_eppi == SSE_SPECIAL) { - ot = (s->dflag == 2) ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); rm = (modrm & 7) | REX_B(s); if (mod != 3) - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); reg = ((modrm >> 3) & 7) | rex_r; val = cpu_ldub_code(env, s->pc++); switch (b) { case 0x14: /* pextrb */ tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_B(val & 15))); - if (mod == 3) - gen_op_mov_reg_T0(ot, rm); - else - tcg_gen_qemu_st8(cpu_T[0], cpu_A0, - (s->mem_index >> 2) - 1); + if (mod == 3) { + gen_op_mov_reg_v(ot, rm, cpu_T[0]); + } else { + tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0, + s->mem_index, MO_UB); + } break; case 0x15: /* pextrw */ tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_W(val & 7))); - if (mod == 3) - gen_op_mov_reg_T0(ot, rm); - else - tcg_gen_qemu_st16(cpu_T[0], cpu_A0, - (s->mem_index >> 2) - 1); + if (mod == 3) { + gen_op_mov_reg_v(ot, rm, cpu_T[0]); + } else { + tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0, + s->mem_index, MO_LEUW); + } break; case 0x16: - if (ot == OT_LONG) { /* pextrd */ + if (ot == MO_32) { /* pextrd */ tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_L(val & 3))); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - if (mod == 3) - gen_op_mov_reg_v(ot, rm, cpu_T[0]); - else - tcg_gen_qemu_st32(cpu_T[0], cpu_A0, - (s->mem_index >> 2) - 1); + if (mod == 3) { + tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32); + } else { + tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); + } } else { /* pextrq */ #ifdef TARGET_X86_64 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_Q(val & 1))); - if (mod == 3) - gen_op_mov_reg_v(ot, rm, cpu_tmp1_i64); - else - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, - (s->mem_index >> 2) - 1); + if (mod == 3) { + tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64); + } else { + tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, + s->mem_index, MO_LEQ); + } #else goto illegal_op; #endif @@ -4408,18 +4124,20 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, case 0x17: /* extractps */ tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_L(val & 3))); - if (mod == 3) - gen_op_mov_reg_T0(ot, rm); - else - tcg_gen_qemu_st32(cpu_T[0], cpu_A0, - (s->mem_index >> 2) - 1); + if (mod == 3) { + gen_op_mov_reg_v(ot, rm, cpu_T[0]); + } else { + tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0, + s->mem_index, MO_LEUL); + } break; case 0x20: /* pinsrb */ - if (mod == 3) - gen_op_mov_TN_reg(OT_LONG, 0, rm); - else - tcg_gen_qemu_ld8u(cpu_T[0], cpu_A0, - (s->mem_index >> 2) - 1); + if (mod == 3) { + gen_op_mov_v_reg(MO_32, cpu_T[0], rm); + } else { + tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0, + s->mem_index, MO_UB); + } tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_B(val & 15))); break; @@ -4429,9 +4147,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, offsetof(CPUX86State,xmm_regs[rm] .XMM_L((val >> 6) & 3))); } else { - tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0, - (s->mem_index >> 2) - 1); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); } tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State,xmm_regs[reg] @@ -4454,23 +4171,24 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, xmm_regs[reg].XMM_L(3))); break; case 0x22: - if (ot == OT_LONG) { /* pinsrd */ - if (mod == 3) - gen_op_mov_v_reg(ot, cpu_tmp0, rm); - else - tcg_gen_qemu_ld32u(cpu_tmp0, cpu_A0, - (s->mem_index >> 2) - 1); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp0); + if (ot == MO_32) { /* pinsrd */ + if (mod == 3) { + tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]); + } else { + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); + } tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_L(val & 3))); } else { /* pinsrq */ #ifdef TARGET_X86_64 - if (mod == 3) + if (mod == 3) { gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm); - else - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, - (s->mem_index >> 2) - 1); + } else { + tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, + s->mem_index, MO_LEQ); + } tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offsetof(CPUX86State, xmm_regs[reg].XMM_Q(val & 1))); @@ -4489,8 +4207,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]); } else { op2_offset = offsetof(CPUX86State,xmm_t0); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldo_env_A0(s->mem_index, op2_offset); + gen_lea_modrm(env, s, modrm); + gen_ldo_env_A0(s, op2_offset); } } else { op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); @@ -4498,8 +4216,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); } else { op2_offset = offsetof(CPUX86State,mmx_t0); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_ldq_env_A0(s->mem_index, op2_offset); + gen_lea_modrm(env, s, modrm); + gen_ldq_env_A0(s, op2_offset); } } val = cpu_ldub_code(env, s->pc++); @@ -4507,9 +4225,10 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, if ((b & 0xfc) == 0x60) { /* pcmpXstrX */ set_cc_op(s, CC_OP_EFLAGS); - if (s->dflag == 2) + if (s->dflag == MO_64) { /* The helper must use entire 64-bit gp registers */ val |= 1 << 8; + } } tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); @@ -4530,17 +4249,17 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, || s->vex_l != 0) { goto illegal_op; } - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); b = cpu_ldub_code(env, s->pc++); - if (ot == OT_QUAD) { + if (ot == MO_64) { tcg_gen_rotri_tl(cpu_T[0], cpu_T[0], b & 63); } else { tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31); tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); } - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; default: @@ -4565,21 +4284,22 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, if (is_xmm) { op1_offset = offsetof(CPUX86State,xmm_regs[reg]); if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,xmm_t0); if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) || b == 0xc2)) { /* specific case for SSE single instructions */ if (b1 == 2) { /* 32 bit access */ - gen_op_ld_T0_A0(OT_LONG + s->mem_index); + gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0); tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0))); } else { /* 64 bit access */ - gen_ldq_env_A0(s->mem_index, offsetof(CPUX86State,xmm_t0.XMM_D(0))); + gen_ldq_env_A0(s, offsetof(CPUX86State, + xmm_t0.XMM_D(0))); } } else { - gen_ldo_env_A0(s->mem_index, op2_offset); + gen_ldo_env_A0(s, op2_offset); } } else { rm = (modrm & 7) | REX_B(s); @@ -4588,9 +4308,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, } else { op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,mmx_t0); - gen_ldq_env_A0(s->mem_index, op2_offset); + gen_ldq_env_A0(s, op2_offset); } else { rm = (modrm & 7); op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); @@ -4633,16 +4353,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, /* maskmov : we must prepare A0 */ if (mod != 3) goto illegal_op; -#ifdef TARGET_X86_64 - if (s->aflag == 2) { - gen_op_movq_A0_reg(R_EDI); - } else -#endif - { - gen_op_movl_A0_reg(R_EDI); - if (s->aflag == 0) - gen_op_andl_A0_ffff(); - } + tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]); + gen_extu(s->aflag, cpu_A0); gen_add_A0_ds_seg(s); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); @@ -4668,9 +4380,10 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, static target_ulong disas_insn(CPUX86State *env, DisasContext *s, target_ulong pc_start) { - int b, prefixes, aflag, dflag; - int shift, ot; - int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val; + int b, prefixes; + int shift; + TCGMemOp ot, aflag, dflag; + int modrm, reg, rm, mod, op, opreg, val; target_ulong next_eip, tval; int rex_w, rex_r; @@ -4805,19 +4518,21 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, /* In 64-bit mode, the default data size is 32-bit. Select 64-bit data with rex_w, and 16-bit data with 0x66; rex_w takes precedence over 0x66 if both are present. */ - dflag = (rex_w > 0 ? 2 : prefixes & PREFIX_DATA ? 0 : 1); + dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32); /* In 64-bit mode, 0x67 selects 32-bit addressing. */ - aflag = (prefixes & PREFIX_ADR ? 1 : 2); + aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64); } else { /* In 16/32-bit mode, 0x66 selects the opposite data size. */ - dflag = s->code32; - if (prefixes & PREFIX_DATA) { - dflag ^= 1; + if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) { + dflag = MO_32; + } else { + dflag = MO_16; } /* In 16/32-bit mode, 0x67 selects the opposite addressing. */ - aflag = s->code32; - if (prefixes & PREFIX_ADR) { - aflag ^= 1; + if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) { + aflag = MO_32; + } else { + aflag = MO_16; } } @@ -4853,10 +4568,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, op = (b >> 3) & 7; f = (b >> 1) & 3; - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); switch(f) { case 0: /* OP Ev, Gv */ @@ -4865,19 +4577,19 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); opreg = OR_TMP0; } else if (op == OP_XORL && rm == reg) { xor_zero: /* xor reg, reg optimisation */ set_cc_op(s, CC_OP_CLR); - gen_op_movl_T0_0(); - gen_op_mov_reg_T0(ot, reg); + tcg_gen_movi_tl(cpu_T[0], 0); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; } else { opreg = rm; } - gen_op_mov_TN_reg(ot, 1, reg); + gen_op_mov_v_reg(ot, cpu_T[1], reg); gen_op(s, op, ot, opreg); break; case 1: /* OP Gv, Ev */ @@ -4886,18 +4598,18 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, reg = ((modrm >> 3) & 7) | rex_r; rm = (modrm & 7) | REX_B(s); if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_ld_T1_A0(ot + s->mem_index); + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, ot, cpu_T[1], cpu_A0); } else if (op == OP_XORL && rm == reg) { goto xor_zero; } else { - gen_op_mov_TN_reg(ot, 1, rm); + gen_op_mov_v_reg(ot, cpu_T[1], rm); } gen_op(s, op, ot, reg); break; case 2: /* OP A, Iv */ val = insn_get(env, s, ot); - gen_op_movl_T1_im(val); + tcg_gen_movi_tl(cpu_T[1], val); gen_op(s, op, ot, OR_EAX); break; } @@ -4913,10 +4625,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, { int val; - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; @@ -4928,7 +4637,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, s->rip_offset = 1; else s->rip_offset = insn_const_size(ot); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); opreg = OR_TMP0; } else { opreg = rm; @@ -4942,10 +4651,10 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, val = insn_get(env, s, ot); break; case 0x83: - val = (int8_t)insn_get(env, s, OT_BYTE); + val = (int8_t)insn_get(env, s, MO_8); break; } - gen_op_movl_T1_im(val); + tcg_gen_movi_tl(cpu_T[1], val); gen_op(s, op, ot, opreg); } break; @@ -4953,19 +4662,16 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, /**************************/ /* inc, dec, and other misc arith */ case 0x40 ... 0x47: /* inc Gv */ - ot = dflag ? OT_LONG : OT_WORD; + ot = dflag; gen_inc(s, ot, OR_EAX + (b & 7), 1); break; case 0x48 ... 0x4f: /* dec Gv */ - ot = dflag ? OT_LONG : OT_WORD; + ot = dflag; gen_inc(s, ot, OR_EAX + (b & 7), -1); break; case 0xf6: /* GRP3 */ case 0xf7: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; @@ -4974,65 +4680,65 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (mod != 3) { if (op == 0) s->rip_offset = insn_const_size(ot); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_ld_T0_A0(ot + s->mem_index); + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_TN_reg(ot, 0, rm); + gen_op_mov_v_reg(ot, cpu_T[0], rm); } switch(op) { case 0: /* test */ val = insn_get(env, s, ot); - gen_op_movl_T1_im(val); + tcg_gen_movi_tl(cpu_T[1], val); gen_op_testl_T0_T1_cc(); set_cc_op(s, CC_OP_LOGICB + ot); break; case 2: /* not */ tcg_gen_not_tl(cpu_T[0], cpu_T[0]); if (mod != 3) { - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_reg_T0(ot, rm); + gen_op_mov_reg_v(ot, rm, cpu_T[0]); } break; case 3: /* neg */ tcg_gen_neg_tl(cpu_T[0], cpu_T[0]); if (mod != 3) { - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_reg_T0(ot, rm); + gen_op_mov_reg_v(ot, rm, cpu_T[0]); } gen_op_update_neg_cc(); set_cc_op(s, CC_OP_SUBB + ot); break; case 4: /* mul */ switch(ot) { - case OT_BYTE: - gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX); + case MO_8: + gen_op_mov_v_reg(MO_8, cpu_T[1], R_EAX); tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]); tcg_gen_ext8u_tl(cpu_T[1], cpu_T[1]); /* XXX: use 32 bit mul which could be faster */ tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - gen_op_mov_reg_T0(OT_WORD, R_EAX); + gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]); tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); tcg_gen_andi_tl(cpu_cc_src, cpu_T[0], 0xff00); set_cc_op(s, CC_OP_MULB); break; - case OT_WORD: - gen_op_mov_TN_reg(OT_WORD, 1, R_EAX); + case MO_16: + gen_op_mov_v_reg(MO_16, cpu_T[1], R_EAX); tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]); tcg_gen_ext16u_tl(cpu_T[1], cpu_T[1]); /* XXX: use 32 bit mul which could be faster */ tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - gen_op_mov_reg_T0(OT_WORD, R_EAX); + gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]); tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16); - gen_op_mov_reg_T0(OT_WORD, R_EDX); + gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]); tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]); set_cc_op(s, CC_OP_MULW); break; default: - case OT_LONG: + case MO_32: tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]); tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32, @@ -5044,7 +4750,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, set_cc_op(s, CC_OP_MULL); break; #ifdef TARGET_X86_64 - case OT_QUAD: + case MO_64: tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_T[0], cpu_regs[R_EAX]); tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); @@ -5056,34 +4762,34 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 5: /* imul */ switch(ot) { - case OT_BYTE: - gen_op_mov_TN_reg(OT_BYTE, 1, R_EAX); + case MO_8: + gen_op_mov_v_reg(MO_8, cpu_T[1], R_EAX); tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]); tcg_gen_ext8s_tl(cpu_T[1], cpu_T[1]); /* XXX: use 32 bit mul which could be faster */ tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - gen_op_mov_reg_T0(OT_WORD, R_EAX); + gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]); tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); tcg_gen_ext8s_tl(cpu_tmp0, cpu_T[0]); tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); set_cc_op(s, CC_OP_MULB); break; - case OT_WORD: - gen_op_mov_TN_reg(OT_WORD, 1, R_EAX); + case MO_16: + gen_op_mov_v_reg(MO_16, cpu_T[1], R_EAX); tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); tcg_gen_ext16s_tl(cpu_T[1], cpu_T[1]); /* XXX: use 32 bit mul which could be faster */ tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - gen_op_mov_reg_T0(OT_WORD, R_EAX); + gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]); tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]); tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 16); - gen_op_mov_reg_T0(OT_WORD, R_EDX); + gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]); set_cc_op(s, CC_OP_MULW); break; default: - case OT_LONG: + case MO_32: tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EAX]); tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32, @@ -5097,7 +4803,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, set_cc_op(s, CC_OP_MULL); break; #ifdef TARGET_X86_64 - case OT_QUAD: + case MO_64: tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX], cpu_T[0], cpu_regs[R_EAX]); tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]); @@ -5110,21 +4816,21 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 6: /* div */ switch(ot) { - case OT_BYTE: + case MO_8: gen_jmp_im(pc_start - s->cs_base); gen_helper_divb_AL(cpu_env, cpu_T[0]); break; - case OT_WORD: + case MO_16: gen_jmp_im(pc_start - s->cs_base); gen_helper_divw_AX(cpu_env, cpu_T[0]); break; default: - case OT_LONG: + case MO_32: gen_jmp_im(pc_start - s->cs_base); gen_helper_divl_EAX(cpu_env, cpu_T[0]); break; #ifdef TARGET_X86_64 - case OT_QUAD: + case MO_64: gen_jmp_im(pc_start - s->cs_base); gen_helper_divq_EAX(cpu_env, cpu_T[0]); break; @@ -5133,21 +4839,21 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 7: /* idiv */ switch(ot) { - case OT_BYTE: + case MO_8: gen_jmp_im(pc_start - s->cs_base); gen_helper_idivb_AL(cpu_env, cpu_T[0]); break; - case OT_WORD: + case MO_16: gen_jmp_im(pc_start - s->cs_base); gen_helper_idivw_AX(cpu_env, cpu_T[0]); break; default: - case OT_LONG: + case MO_32: gen_jmp_im(pc_start - s->cs_base); gen_helper_idivl_EAX(cpu_env, cpu_T[0]); break; #ifdef TARGET_X86_64 - case OT_QUAD: + case MO_64: gen_jmp_im(pc_start - s->cs_base); gen_helper_idivq_EAX(cpu_env, cpu_T[0]); break; @@ -5161,10 +4867,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0xfe: /* GRP4 */ case 0xff: /* GRP5 */ - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; @@ -5176,20 +4879,20 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (CODE64(s)) { if (op == 2 || op == 4) { /* operand size for jumps is 64 bit */ - ot = OT_QUAD; + ot = MO_64; } else if (op == 3 || op == 5) { - ot = dflag ? OT_LONG + (rex_w == 1) : OT_WORD; + ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16; } else if (op == 6) { /* default push size is 64 bit */ - ot = dflag ? OT_QUAD : OT_WORD; + ot = mo_pushpop(s, dflag); } } if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); if (op >= 2 && op != 3 && op != 5) - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_TN_reg(ot, 0, rm); + gen_op_mov_v_reg(ot, cpu_T[0], rm); } switch(op) { @@ -5209,44 +4912,46 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 2: /* call Ev */ /* XXX: optimize if memory (no 'and' is necessary) */ - if (s->dflag == 0) - gen_op_andl_T0_ffff(); + if (dflag == MO_16) { + tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]); + } next_eip = s->pc - s->cs_base; - gen_movtl_T1_im(next_eip); - gen_push_T1(s); - gen_op_jmp_T0(); + tcg_gen_movi_tl(cpu_T[1], next_eip); + gen_push_v(s, cpu_T[1]); + gen_op_jmp_v(cpu_T[0]); gen_eob(s); break; case 3: /* lcall Ev */ - gen_op_ld_T1_A0(ot + s->mem_index); - gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); - gen_op_ldu_T0_A0(OT_WORD + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[1], cpu_A0); + gen_add_A0_im(s, 1 << ot); + gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0); do_lcall: if (s->pe && !s->vm86) { gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_lcall_protected(cpu_env, cpu_tmp2_i32, cpu_T[1], - tcg_const_i32(dflag), + tcg_const_i32(dflag - 1), tcg_const_i32(s->pc - pc_start)); } else { tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_lcall_real(cpu_env, cpu_tmp2_i32, cpu_T[1], - tcg_const_i32(dflag), + tcg_const_i32(dflag - 1), tcg_const_i32(s->pc - s->cs_base)); } gen_eob(s); break; case 4: /* jmp Ev */ - if (s->dflag == 0) - gen_op_andl_T0_ffff(); - gen_op_jmp_T0(); + if (dflag == MO_16) { + tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]); + } + gen_op_jmp_v(cpu_T[0]); gen_eob(s); break; case 5: /* ljmp Ev */ - gen_op_ld_T1_A0(ot + s->mem_index); - gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); - gen_op_ldu_T0_A0(OT_WORD + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[1], cpu_A0); + gen_add_A0_im(s, 1 << ot); + gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0); do_ljmp: if (s->pe && !s->vm86) { gen_update_cc_op(s); @@ -5256,13 +4961,12 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, tcg_const_i32(s->pc - pc_start)); } else { gen_op_movl_seg_T0_vm(R_CS); - gen_op_movl_T0_T1(); - gen_op_jmp_T0(); + gen_op_jmp_v(cpu_T[1]); } gen_eob(s); break; case 6: /* push Ev */ - gen_push_T0(s); + gen_push_v(s, cpu_T[0]); break; default: goto illegal_op; @@ -5271,76 +4975,80 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x84: /* test Ev, Gv */ case 0x85: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); - gen_op_mov_TN_reg(ot, 1, reg); + gen_op_mov_v_reg(ot, cpu_T[1], reg); gen_op_testl_T0_T1_cc(); set_cc_op(s, CC_OP_LOGICB + ot); break; case 0xa8: /* test eAX, Iv */ case 0xa9: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); val = insn_get(env, s, ot); - gen_op_mov_TN_reg(ot, 0, OR_EAX); - gen_op_movl_T1_im(val); + gen_op_mov_v_reg(ot, cpu_T[0], OR_EAX); + tcg_gen_movi_tl(cpu_T[1], val); gen_op_testl_T0_T1_cc(); set_cc_op(s, CC_OP_LOGICB + ot); break; case 0x98: /* CWDE/CBW */ + switch (dflag) { #ifdef TARGET_X86_64 - if (dflag == 2) { - gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); + case MO_64: + gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX); tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - gen_op_mov_reg_T0(OT_QUAD, R_EAX); - } else + gen_op_mov_reg_v(MO_64, R_EAX, cpu_T[0]); + break; #endif - if (dflag == 1) { - gen_op_mov_TN_reg(OT_WORD, 0, R_EAX); + case MO_32: + gen_op_mov_v_reg(MO_16, cpu_T[0], R_EAX); tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); - gen_op_mov_reg_T0(OT_LONG, R_EAX); - } else { - gen_op_mov_TN_reg(OT_BYTE, 0, R_EAX); + gen_op_mov_reg_v(MO_32, R_EAX, cpu_T[0]); + break; + case MO_16: + gen_op_mov_v_reg(MO_8, cpu_T[0], R_EAX); tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]); - gen_op_mov_reg_T0(OT_WORD, R_EAX); + gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]); + break; + default: + tcg_abort(); } break; case 0x99: /* CDQ/CWD */ + switch (dflag) { #ifdef TARGET_X86_64 - if (dflag == 2) { - gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX); + case MO_64: + gen_op_mov_v_reg(MO_64, cpu_T[0], R_EAX); tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 63); - gen_op_mov_reg_T0(OT_QUAD, R_EDX); - } else + gen_op_mov_reg_v(MO_64, R_EDX, cpu_T[0]); + break; #endif - if (dflag == 1) { - gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); + case MO_32: + gen_op_mov_v_reg(MO_32, cpu_T[0], R_EAX); tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 31); - gen_op_mov_reg_T0(OT_LONG, R_EDX); - } else { - gen_op_mov_TN_reg(OT_WORD, 0, R_EAX); + gen_op_mov_reg_v(MO_32, R_EDX, cpu_T[0]); + break; + case MO_16: + gen_op_mov_v_reg(MO_16, cpu_T[0], R_EAX); tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); tcg_gen_sari_tl(cpu_T[0], cpu_T[0], 15); - gen_op_mov_reg_T0(OT_WORD, R_EDX); + gen_op_mov_reg_v(MO_16, R_EDX, cpu_T[0]); + break; + default: + tcg_abort(); } break; case 0x1af: /* imul Gv, Ev */ case 0x69: /* imul Gv, Ev, I */ case 0x6b: - ot = dflag + OT_WORD; + ot = dflag; modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; if (b == 0x69) @@ -5350,23 +5058,23 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); if (b == 0x69) { val = insn_get(env, s, ot); - gen_op_movl_T1_im(val); + tcg_gen_movi_tl(cpu_T[1], val); } else if (b == 0x6b) { - val = (int8_t)insn_get(env, s, OT_BYTE); - gen_op_movl_T1_im(val); + val = (int8_t)insn_get(env, s, MO_8); + tcg_gen_movi_tl(cpu_T[1], val); } else { - gen_op_mov_TN_reg(ot, 1, reg); + gen_op_mov_v_reg(ot, cpu_T[1], reg); } switch (ot) { #ifdef TARGET_X86_64 - case OT_QUAD: + case MO_64: tcg_gen_muls2_i64(cpu_regs[reg], cpu_T[1], cpu_T[0], cpu_T[1]); tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]); tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63); tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_T[1]); break; #endif - case OT_LONG: + case MO_32: tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]); tcg_gen_muls2_i32(cpu_tmp2_i32, cpu_tmp3_i32, @@ -5385,34 +5093,31 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); tcg_gen_ext16s_tl(cpu_tmp0, cpu_T[0]); tcg_gen_sub_tl(cpu_cc_src, cpu_T[0], cpu_tmp0); - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; } set_cc_op(s, CC_OP_MULB + ot); break; case 0x1c0: case 0x1c1: /* xadd Ev, Gv */ - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; if (mod == 3) { rm = (modrm & 7) | REX_B(s); - gen_op_mov_TN_reg(ot, 0, reg); - gen_op_mov_TN_reg(ot, 1, rm); - gen_op_addl_T0_T1(); - gen_op_mov_reg_T1(ot, reg); - gen_op_mov_reg_T0(ot, rm); + gen_op_mov_v_reg(ot, cpu_T[0], reg); + gen_op_mov_v_reg(ot, cpu_T[1], rm); + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + gen_op_mov_reg_v(ot, reg, cpu_T[1]); + gen_op_mov_reg_v(ot, rm, cpu_T[0]); } else { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_mov_TN_reg(ot, 0, reg); - gen_op_ld_T1_A0(ot + s->mem_index); - gen_op_addl_T0_T1(); - gen_op_st_T0_A0(ot + s->mem_index); - gen_op_mov_reg_T1(ot, reg); + gen_lea_modrm(env, s, modrm); + gen_op_mov_v_reg(ot, cpu_T[0], reg); + gen_op_ld_v(s, ot, cpu_T[1], cpu_A0); + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); + gen_op_mov_reg_v(ot, reg, cpu_T[1]); } gen_op_update2_cc(); set_cc_op(s, CC_OP_ADDB + ot); @@ -5423,10 +5128,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, int label1, label2; TCGv t0, t1, t2, a0; - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; @@ -5439,9 +5141,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, rm = (modrm & 7) | REX_B(s); gen_op_mov_v_reg(ot, t0, rm); } else { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); tcg_gen_mov_tl(a0, cpu_A0); - gen_op_ld_v(ot + s->mem_index, t0, a0); + gen_op_ld_v(s, ot, t0, a0); rm = 0; /* avoid warning */ } label1 = gen_new_label(); @@ -5459,11 +5161,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, /* perform no-op store cycle like physical cpu; must be before changing accumulator to ensure idempotency if the store faults and the instruction is restarted */ - gen_op_st_v(ot + s->mem_index, t0, a0); + gen_op_st_v(s, ot, t0, a0); gen_op_mov_reg_v(ot, R_EAX, t0); tcg_gen_br(label2); gen_set_label(label1); - gen_op_st_v(ot + s->mem_index, t1, a0); + gen_op_st_v(s, ot, t1, a0); } gen_set_label(label2); tcg_gen_mov_tl(cpu_cc_src, t0); @@ -5482,12 +5184,12 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if ((mod == 3) || ((modrm & 0x38) != 0x8)) goto illegal_op; #ifdef TARGET_X86_64 - if (dflag == 2) { + if (dflag == MO_64) { if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) goto illegal_op; gen_jmp_im(pc_start - s->cs_base); gen_update_cc_op(s); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); gen_helper_cmpxchg16b(cpu_env, cpu_A0); } else #endif @@ -5496,7 +5198,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; gen_jmp_im(pc_start - s->cs_base); gen_update_cc_op(s); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); gen_helper_cmpxchg8b(cpu_env, cpu_A0); } set_cc_op(s, CC_OP_EFLAGS); @@ -5505,19 +5207,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, /**************************/ /* push/pop */ case 0x50 ... 0x57: /* push */ - gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s)); - gen_push_T0(s); + gen_op_mov_v_reg(MO_32, cpu_T[0], (b & 7) | REX_B(s)); + gen_push_v(s, cpu_T[0]); break; case 0x58 ... 0x5f: /* pop */ - if (CODE64(s)) { - ot = dflag ? OT_QUAD : OT_WORD; - } else { - ot = dflag + OT_WORD; - } - gen_pop_T0(s); + ot = gen_pop_T0(s); /* NOTE: order is important for pop %sp */ - gen_pop_update(s); - gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s)); + gen_pop_update(s, ot); + gen_op_mov_reg_v(ot, (b & 7) | REX_B(s), cpu_T[0]); break; case 0x60: /* pusha */ if (CODE64(s)) @@ -5531,38 +5228,29 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0x68: /* push Iv */ case 0x6a: - if (CODE64(s)) { - ot = dflag ? OT_QUAD : OT_WORD; - } else { - ot = dflag + OT_WORD; - } + ot = mo_pushpop(s, dflag); if (b == 0x68) val = insn_get(env, s, ot); else - val = (int8_t)insn_get(env, s, OT_BYTE); - gen_op_movl_T0_im(val); - gen_push_T0(s); + val = (int8_t)insn_get(env, s, MO_8); + tcg_gen_movi_tl(cpu_T[0], val); + gen_push_v(s, cpu_T[0]); break; case 0x8f: /* pop Ev */ - if (CODE64(s)) { - ot = dflag ? OT_QUAD : OT_WORD; - } else { - ot = dflag + OT_WORD; - } modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; - gen_pop_T0(s); + ot = gen_pop_T0(s); if (mod == 3) { /* NOTE: order is important for pop %sp */ - gen_pop_update(s); + gen_pop_update(s, ot); rm = (modrm & 7) | REX_B(s); - gen_op_mov_reg_T0(ot, rm); + gen_op_mov_reg_v(ot, rm, cpu_T[0]); } else { /* NOTE: order is important too for MMU exceptions */ s->popl_esp_hack = 1 << ot; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); s->popl_esp_hack = 0; - gen_pop_update(s); + gen_pop_update(s, ot); } break; case 0xc8: /* enter */ @@ -5577,23 +5265,18 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0xc9: /* leave */ /* XXX: exception not precise (ESP is updated before potential exception) */ if (CODE64(s)) { - gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP); - gen_op_mov_reg_T0(OT_QUAD, R_ESP); + gen_op_mov_v_reg(MO_64, cpu_T[0], R_EBP); + gen_op_mov_reg_v(MO_64, R_ESP, cpu_T[0]); } else if (s->ss32) { - gen_op_mov_TN_reg(OT_LONG, 0, R_EBP); - gen_op_mov_reg_T0(OT_LONG, R_ESP); - } else { - gen_op_mov_TN_reg(OT_WORD, 0, R_EBP); - gen_op_mov_reg_T0(OT_WORD, R_ESP); - } - gen_pop_T0(s); - if (CODE64(s)) { - ot = dflag ? OT_QUAD : OT_WORD; + gen_op_mov_v_reg(MO_32, cpu_T[0], R_EBP); + gen_op_mov_reg_v(MO_32, R_ESP, cpu_T[0]); } else { - ot = dflag + OT_WORD; + gen_op_mov_v_reg(MO_16, cpu_T[0], R_EBP); + gen_op_mov_reg_v(MO_16, R_ESP, cpu_T[0]); } - gen_op_mov_reg_T0(ot, R_EBP); - gen_pop_update(s); + ot = gen_pop_T0(s); + gen_op_mov_reg_v(ot, R_EBP, cpu_T[0]); + gen_pop_update(s, ot); break; case 0x06: /* push es */ case 0x0e: /* push cs */ @@ -5602,12 +5285,12 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (CODE64(s)) goto illegal_op; gen_op_movl_T0_seg(b >> 3); - gen_push_T0(s); + gen_push_v(s, cpu_T[0]); break; case 0x1a0: /* push fs */ case 0x1a8: /* push gs */ gen_op_movl_T0_seg((b >> 3) & 7); - gen_push_T0(s); + gen_push_v(s, cpu_T[0]); break; case 0x07: /* pop es */ case 0x17: /* pop ss */ @@ -5615,9 +5298,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (CODE64(s)) goto illegal_op; reg = b >> 3; - gen_pop_T0(s); + ot = gen_pop_T0(s); gen_movl_seg_T0(s, reg, pc_start - s->cs_base); - gen_pop_update(s); + gen_pop_update(s, ot); if (reg == R_SS) { /* if reg == SS, inhibit interrupts/trace. */ /* If several instructions disable interrupts, only the @@ -5633,9 +5316,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0x1a1: /* pop fs */ case 0x1a9: /* pop gs */ - gen_pop_T0(s); + ot = gen_pop_T0(s); gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base); - gen_pop_update(s); + gen_pop_update(s, ot); if (s->is_jmp) { gen_jmp_im(s->pc - s->cs_base); gen_eob(s); @@ -5646,10 +5329,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, /* mov */ case 0x88: case 0x89: /* mov Gv, Ev */ - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; @@ -5658,41 +5338,36 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0xc6: case 0xc7: /* mov Ev, Iv */ - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; if (mod != 3) { s->rip_offset = insn_const_size(ot); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); } val = insn_get(env, s, ot); - gen_op_movl_T0_im(val); - if (mod != 3) - gen_op_st_T0_A0(ot + s->mem_index); - else - gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s)); + tcg_gen_movi_tl(cpu_T[0], val); + if (mod != 3) { + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); + } else { + gen_op_mov_reg_v(ot, (modrm & 7) | REX_B(s), cpu_T[0]); + } break; case 0x8a: case 0x8b: /* mov Ev, Gv */ - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = OT_WORD + dflag; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; case 0x8e: /* mov seg, Gv */ modrm = cpu_ldub_code(env, s->pc++); reg = (modrm >> 3) & 7; if (reg >= 6 || reg == R_CS) goto illegal_op; - gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); gen_movl_seg_T0(s, reg, pc_start - s->cs_base); if (reg == R_SS) { /* if reg == SS, inhibit interrupts/trace */ @@ -5714,10 +5389,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (reg >= 6) goto illegal_op; gen_op_movl_T0_seg(reg); - if (mod == 3) - ot = OT_WORD + dflag; - else - ot = OT_WORD; + ot = mod == 3 ? dflag : MO_16; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); break; @@ -5726,48 +5398,49 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x1be: /* movsbS Gv, Eb */ case 0x1bf: /* movswS Gv, Eb */ { - int d_ot; + TCGMemOp d_ot; + TCGMemOp s_ot; + /* d_ot is the size of destination */ - d_ot = dflag + OT_WORD; + d_ot = dflag; /* ot is the size of source */ - ot = (b & 1) + OT_BYTE; + ot = (b & 1) + MO_8; + /* s_ot is the sign+size of source */ + s_ot = b & 8 ? MO_SIGN | ot : ot; + modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); if (mod == 3) { - gen_op_mov_TN_reg(ot, 0, rm); - switch(ot | (b & 8)) { - case OT_BYTE: + gen_op_mov_v_reg(ot, cpu_T[0], rm); + switch (s_ot) { + case MO_UB: tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]); break; - case OT_BYTE | 8: + case MO_SB: tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]); break; - case OT_WORD: + case MO_UW: tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]); break; default: - case OT_WORD | 8: + case MO_SW: tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); break; } - gen_op_mov_reg_T0(d_ot, reg); + gen_op_mov_reg_v(d_ot, reg, cpu_T[0]); } else { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - if (b & 8) { - gen_op_lds_T0_A0(ot + s->mem_index); - } else { - gen_op_ldu_T0_A0(ot + s->mem_index); - } - gen_op_mov_reg_T0(d_ot, reg); + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, s_ot, cpu_T[0], cpu_A0); + gen_op_mov_reg_v(d_ot, reg, cpu_T[0]); } } break; case 0x8d: /* lea */ - ot = dflag + OT_WORD; + ot = dflag; modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; if (mod == 3) @@ -5777,9 +5450,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, s->override = -1; val = s->addseg; s->addseg = 0; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); s->addseg = val; - gen_op_mov_reg_A0(ot - OT_WORD, reg); + gen_op_mov_reg_v(ot, reg, cpu_A0); break; case 0xa0: /* mov EAX, Ov */ @@ -5789,117 +5462,94 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, { target_ulong offset_addr; - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); + switch (s->aflag) { #ifdef TARGET_X86_64 - if (s->aflag == 2) { + case MO_64: offset_addr = cpu_ldq_code(env, s->pc); s->pc += 8; - gen_op_movq_A0_im(offset_addr); - } else + break; #endif - { - if (s->aflag) { - offset_addr = insn_get(env, s, OT_LONG); - } else { - offset_addr = insn_get(env, s, OT_WORD); - } - gen_op_movl_A0_im(offset_addr); + default: + offset_addr = insn_get(env, s, s->aflag); + break; } + tcg_gen_movi_tl(cpu_A0, offset_addr); gen_add_A0_ds_seg(s); if ((b & 2) == 0) { - gen_op_ld_T0_A0(ot + s->mem_index); - gen_op_mov_reg_T0(ot, R_EAX); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); + gen_op_mov_reg_v(ot, R_EAX, cpu_T[0]); } else { - gen_op_mov_TN_reg(ot, 0, R_EAX); - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_mov_v_reg(ot, cpu_T[0], R_EAX); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); } } break; case 0xd7: /* xlat */ -#ifdef TARGET_X86_64 - if (s->aflag == 2) { - gen_op_movq_A0_reg(R_EBX); - gen_op_mov_TN_reg(OT_QUAD, 0, R_EAX); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff); - tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]); - } else -#endif - { - gen_op_movl_A0_reg(R_EBX); - gen_op_mov_TN_reg(OT_LONG, 0, R_EAX); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xff); - tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]); - if (s->aflag == 0) - gen_op_andl_A0_ffff(); - else - tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff); - } + tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EBX]); + tcg_gen_ext8u_tl(cpu_T[0], cpu_regs[R_EAX]); + tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_T[0]); + gen_extu(s->aflag, cpu_A0); gen_add_A0_ds_seg(s); - gen_op_ldu_T0_A0(OT_BYTE + s->mem_index); - gen_op_mov_reg_T0(OT_BYTE, R_EAX); + gen_op_ld_v(s, MO_8, cpu_T[0], cpu_A0); + gen_op_mov_reg_v(MO_8, R_EAX, cpu_T[0]); break; case 0xb0 ... 0xb7: /* mov R, Ib */ - val = insn_get(env, s, OT_BYTE); - gen_op_movl_T0_im(val); - gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s)); + val = insn_get(env, s, MO_8); + tcg_gen_movi_tl(cpu_T[0], val); + gen_op_mov_reg_v(MO_8, (b & 7) | REX_B(s), cpu_T[0]); break; case 0xb8 ... 0xbf: /* mov R, Iv */ #ifdef TARGET_X86_64 - if (dflag == 2) { + if (dflag == MO_64) { uint64_t tmp; /* 64 bit case */ tmp = cpu_ldq_code(env, s->pc); s->pc += 8; reg = (b & 7) | REX_B(s); - gen_movtl_T0_im(tmp); - gen_op_mov_reg_T0(OT_QUAD, reg); + tcg_gen_movi_tl(cpu_T[0], tmp); + gen_op_mov_reg_v(MO_64, reg, cpu_T[0]); } else #endif { - ot = dflag ? OT_LONG : OT_WORD; + ot = dflag; val = insn_get(env, s, ot); reg = (b & 7) | REX_B(s); - gen_op_movl_T0_im(val); - gen_op_mov_reg_T0(ot, reg); + tcg_gen_movi_tl(cpu_T[0], val); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); } break; case 0x91 ... 0x97: /* xchg R, EAX */ do_xchg_reg_eax: - ot = dflag + OT_WORD; + ot = dflag; reg = (b & 7) | REX_B(s); rm = R_EAX; goto do_xchg_reg; case 0x86: case 0x87: /* xchg Ev, Gv */ - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; if (mod == 3) { rm = (modrm & 7) | REX_B(s); do_xchg_reg: - gen_op_mov_TN_reg(ot, 0, reg); - gen_op_mov_TN_reg(ot, 1, rm); - gen_op_mov_reg_T0(ot, rm); - gen_op_mov_reg_T1(ot, reg); + gen_op_mov_v_reg(ot, cpu_T[0], reg); + gen_op_mov_v_reg(ot, cpu_T[1], rm); + gen_op_mov_reg_v(ot, rm, cpu_T[0]); + gen_op_mov_reg_v(ot, reg, cpu_T[1]); } else { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_mov_TN_reg(ot, 0, reg); + gen_lea_modrm(env, s, modrm); + gen_op_mov_v_reg(ot, cpu_T[0], reg); /* for xchg, lock is implicit */ if (!(prefixes & PREFIX_LOCK)) gen_helper_lock(); - gen_op_ld_T1_A0(ot + s->mem_index); - gen_op_st_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[1], cpu_A0); + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); if (!(prefixes & PREFIX_LOCK)) gen_helper_unlock(); - gen_op_mov_reg_T1(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[1]); } break; case 0xc4: /* les Gv */ @@ -5919,20 +5569,20 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x1b5: /* lgs Gv */ op = R_GS; do_lxx: - ot = dflag ? OT_LONG : OT_WORD; + ot = dflag != MO_16 ? MO_32 : MO_16; modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; if (mod == 3) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_ld_T1_A0(ot + s->mem_index); - gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, ot, cpu_T[1], cpu_A0); + gen_add_A0_im(s, 1 << ot); /* load the segment first to handle exceptions properly */ - gen_op_ldu_T0_A0(OT_WORD + s->mem_index); + gen_op_ld_v(s, MO_16, cpu_T[0], cpu_A0); gen_movl_seg_T0(s, op, pc_start - s->cs_base); /* then put the data */ - gen_op_mov_reg_T1(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[1]); if (s->is_jmp) { gen_jmp_im(s->pc - s->cs_base); gen_eob(s); @@ -5947,11 +5597,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, shift = 2; grp2: { - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; - + ot = mo_b_d(b, dflag); modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; op = (modrm >> 3) & 7; @@ -5960,7 +5606,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (shift == 2) { s->rip_offset = 1; } - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); opreg = OR_TMP0; } else { opreg = (modrm & 7) | REX_B(s); @@ -6004,18 +5650,18 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, op = 1; shift = 0; do_shiftd: - ot = dflag + OT_WORD; + ot = dflag; modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); opreg = OR_TMP0; } else { opreg = rm; } - gen_op_mov_TN_reg(ot, 1, reg); + gen_op_mov_v_reg(ot, cpu_T[1], reg); if (shift) { TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++)); @@ -6041,7 +5687,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, op = ((b & 7) << 3) | ((modrm >> 3) & 7); if (mod != 3) { /* memory op */ - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); switch(op) { case 0x00 ... 0x07: /* fxxxs */ case 0x10 ... 0x17: /* fixxxl */ @@ -6053,24 +5699,24 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, switch(op >> 4) { case 0: - gen_op_ld_T0_A0(OT_LONG + s->mem_index); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32); break; case 1: - gen_op_ld_T0_A0(OT_LONG + s->mem_index); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32); break; case 2: - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, - (s->mem_index >> 2) - 1); + tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, + s->mem_index, MO_LEQ); gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64); break; case 3: default: - gen_op_lds_T0_A0(OT_WORD + s->mem_index); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LESW); gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32); break; } @@ -6092,24 +5738,24 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0: switch(op >> 4) { case 0: - gen_op_ld_T0_A0(OT_LONG + s->mem_index); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32); break; case 1: - gen_op_ld_T0_A0(OT_LONG + s->mem_index); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32); break; case 2: - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, - (s->mem_index >> 2) - 1); + tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, + s->mem_index, MO_LEQ); gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64); break; case 3: default: - gen_op_lds_T0_A0(OT_WORD + s->mem_index); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LESW); gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32); break; } @@ -6119,19 +5765,19 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, switch(op >> 4) { case 1: gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_st_T0_A0(OT_LONG + s->mem_index); + tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); break; case 2: gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, - (s->mem_index >> 2) - 1); + tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, + s->mem_index, MO_LEQ); break; case 3: default: gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_st_T0_A0(OT_WORD + s->mem_index); + tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUW); break; } gen_helper_fpop(cpu_env); @@ -6140,24 +5786,24 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, switch(op >> 4) { case 0: gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_st_T0_A0(OT_LONG + s->mem_index); + tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); break; case 1: gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_st_T0_A0(OT_LONG + s->mem_index); + tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); break; case 2: gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, - (s->mem_index >> 2) - 1); + tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, + s->mem_index, MO_LEQ); break; case 3: default: gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_st_T0_A0(OT_WORD + s->mem_index); + tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUW); break; } if ((op & 7) == 3) @@ -6168,22 +5814,22 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x0c: /* fldenv mem */ gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag)); + gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1)); break; case 0x0d: /* fldcw mem */ - gen_op_ld_T0_A0(OT_WORD + s->mem_index); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUW); gen_helper_fldcw(cpu_env, cpu_tmp2_i32); break; case 0x0e: /* fnstenv mem */ gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(s->dflag)); + gen_helper_fstenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1)); break; case 0x0f: /* fnstcw mem */ gen_helper_fnstcw(cpu_tmp2_i32, cpu_env); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_st_T0_A0(OT_WORD + s->mem_index); + tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUW); break; case 0x1d: /* fldt mem */ gen_update_cc_op(s); @@ -6199,17 +5845,17 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x2c: /* frstor mem */ gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(s->dflag)); + gen_helper_frstor(cpu_env, cpu_A0, tcg_const_i32(dflag - 1)); break; case 0x2e: /* fnsave mem */ gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(s->dflag)); + gen_helper_fsave(cpu_env, cpu_A0, tcg_const_i32(dflag - 1)); break; case 0x2f: /* fnstsw mem */ gen_helper_fnstsw(cpu_tmp2_i32, cpu_env); - tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_st_T0_A0(OT_WORD + s->mem_index); + tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUW); break; case 0x3c: /* fbld */ gen_update_cc_op(s); @@ -6223,14 +5869,12 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_helper_fpop(cpu_env); break; case 0x3d: /* fildll */ - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, - (s->mem_index >> 2) - 1); + tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ); gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64); break; case 0x3f: /* fistpll */ gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, - (s->mem_index >> 2) - 1); + tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ); gen_helper_fpop(cpu_env); break; default: @@ -6496,7 +6140,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0: gen_helper_fnstsw(cpu_tmp2_i32, cpu_env); tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); - gen_op_mov_reg_T0(OT_WORD, R_EAX); + gen_op_mov_reg_v(MO_16, R_EAX, cpu_T[0]); break; default: goto illegal_op; @@ -6553,11 +6197,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0xa4: /* movsS */ case 0xa5: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; - + ot = mo_b_d(b, dflag); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); } else { @@ -6567,11 +6207,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0xaa: /* stosS */ case 0xab: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; - + ot = mo_b_d(b, dflag); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); } else { @@ -6580,10 +6216,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0xac: /* lodsS */ case 0xad: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); } else { @@ -6592,10 +6225,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0xae: /* scasS */ case 0xaf: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); if (prefixes & PREFIX_REPNZ) { gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1); } else if (prefixes & PREFIX_REPZ) { @@ -6607,10 +6237,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0xa6: /* cmpsS */ case 0xa7: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag + OT_WORD; + ot = mo_b_d(b, dflag); if (prefixes & PREFIX_REPNZ) { gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1); } else if (prefixes & PREFIX_REPZ) { @@ -6621,12 +6248,8 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0x6c: /* insS */ case 0x6d: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag ? OT_LONG : OT_WORD; - gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); - gen_op_andl_T0_ffff(); + ot = mo_b_d32(b, dflag); + tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]); gen_check_io(s, ot, pc_start - s->cs_base, SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { @@ -6640,12 +6263,8 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0x6e: /* outsS */ case 0x6f: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag ? OT_LONG : OT_WORD; - gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); - gen_op_andl_T0_ffff(); + ot = mo_b_d32(b, dflag); + tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]); gen_check_io(s, ot, pc_start - s->cs_base, svm_is_rep(prefixes) | 4); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { @@ -6663,19 +6282,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0xe4: case 0xe5: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag ? OT_LONG : OT_WORD; + ot = mo_b_d32(b, dflag); val = cpu_ldub_code(env, s->pc++); - gen_op_movl_T0_im(val); gen_check_io(s, ot, pc_start - s->cs_base, SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes)); if (use_icount) gen_io_start(); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_movi_i32(cpu_tmp2_i32, val); gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32); - gen_op_mov_reg_T1(ot, R_EAX); + gen_op_mov_reg_v(ot, R_EAX, cpu_T[1]); if (use_icount) { gen_io_end(); gen_jmp(s, s->pc - s->cs_base); @@ -6683,19 +6298,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0xe6: case 0xe7: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag ? OT_LONG : OT_WORD; + ot = mo_b_d32(b, dflag); val = cpu_ldub_code(env, s->pc++); - gen_op_movl_T0_im(val); gen_check_io(s, ot, pc_start - s->cs_base, svm_is_rep(prefixes)); - gen_op_mov_TN_reg(ot, 1, R_EAX); + gen_op_mov_v_reg(ot, cpu_T[1], R_EAX); if (use_icount) gen_io_start(); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_movi_i32(cpu_tmp2_i32, val); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]); gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32); if (use_icount) { @@ -6705,19 +6316,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0xec: case 0xed: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag ? OT_LONG : OT_WORD; - gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); - gen_op_andl_T0_ffff(); + ot = mo_b_d32(b, dflag); + tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]); gen_check_io(s, ot, pc_start - s->cs_base, SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes)); if (use_icount) gen_io_start(); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32); - gen_op_mov_reg_T1(ot, R_EAX); + gen_op_mov_reg_v(ot, R_EAX, cpu_T[1]); if (use_icount) { gen_io_end(); gen_jmp(s, s->pc - s->cs_base); @@ -6725,15 +6332,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0xee: case 0xef: - if ((b & 1) == 0) - ot = OT_BYTE; - else - ot = dflag ? OT_LONG : OT_WORD; - gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); - gen_op_andl_T0_ffff(); + ot = mo_b_d32(b, dflag); + tcg_gen_ext16u_tl(cpu_T[0], cpu_regs[R_EDX]); gen_check_io(s, ot, pc_start - s->cs_base, svm_is_rep(prefixes)); - gen_op_mov_TN_reg(ot, 1, R_EAX); + gen_op_mov_v_reg(ot, cpu_T[1], R_EAX); if (use_icount) gen_io_start(); @@ -6751,21 +6354,17 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0xc2: /* ret im */ val = cpu_ldsw_code(env, s->pc); s->pc += 2; - gen_pop_T0(s); - if (CODE64(s) && s->dflag) - s->dflag = 2; - gen_stack_update(s, val + (2 << s->dflag)); - if (s->dflag == 0) - gen_op_andl_T0_ffff(); - gen_op_jmp_T0(); + ot = gen_pop_T0(s); + gen_stack_update(s, val + (1 << ot)); + /* Note that gen_pop_T0 uses a zero-extending load. */ + gen_op_jmp_v(cpu_T[0]); gen_eob(s); break; case 0xc3: /* ret */ - gen_pop_T0(s); - gen_pop_update(s); - if (s->dflag == 0) - gen_op_andl_T0_ffff(); - gen_op_jmp_T0(); + ot = gen_pop_T0(s); + gen_pop_update(s, ot); + /* Note that gen_pop_T0 uses a zero-extending load. */ + gen_op_jmp_v(cpu_T[0]); gen_eob(s); break; case 0xca: /* lret im */ @@ -6775,23 +6374,21 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (s->pe && !s->vm86) { gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_lret_protected(cpu_env, tcg_const_i32(s->dflag), + gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1), tcg_const_i32(val)); } else { gen_stack_A0(s); /* pop offset */ - gen_op_ld_T0_A0(1 + s->dflag + s->mem_index); - if (s->dflag == 0) - gen_op_andl_T0_ffff(); + gen_op_ld_v(s, dflag, cpu_T[0], cpu_A0); /* NOTE: keeping EIP updated is not a problem in case of exception */ - gen_op_jmp_T0(); + gen_op_jmp_v(cpu_T[0]); /* pop selector */ - gen_op_addl_A0_im(2 << s->dflag); - gen_op_ld_T0_A0(1 + s->dflag + s->mem_index); + gen_op_addl_A0_im(1 << dflag); + gen_op_ld_v(s, dflag, cpu_T[0], cpu_A0); gen_op_movl_seg_T0_vm(R_CS); /* add stack offset */ - gen_stack_update(s, val + (4 << s->dflag)); + gen_stack_update(s, val + (2 << dflag)); } gen_eob(s); break; @@ -6802,19 +6399,19 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET); if (!s->pe) { /* real mode */ - gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag)); + gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1)); set_cc_op(s, CC_OP_EFLAGS); } else if (s->vm86) { if (s->iopl != 3) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { - gen_helper_iret_real(cpu_env, tcg_const_i32(s->dflag)); + gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1)); set_cc_op(s, CC_OP_EFLAGS); } } else { gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_iret_protected(cpu_env, tcg_const_i32(s->dflag), + gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1), tcg_const_i32(s->pc - s->cs_base)); set_cc_op(s, CC_OP_EFLAGS); } @@ -6822,18 +6419,20 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, break; case 0xe8: /* call im */ { - if (dflag) - tval = (int32_t)insn_get(env, s, OT_LONG); - else - tval = (int16_t)insn_get(env, s, OT_WORD); + if (dflag != MO_16) { + tval = (int32_t)insn_get(env, s, MO_32); + } else { + tval = (int16_t)insn_get(env, s, MO_16); + } next_eip = s->pc - s->cs_base; tval += next_eip; - if (s->dflag == 0) + if (dflag == MO_16) { tval &= 0xffff; - else if(!CODE64(s)) + } else if (!CODE64(s)) { tval &= 0xffffffff; - gen_movtl_T0_im(next_eip); - gen_push_T0(s); + } + tcg_gen_movi_tl(cpu_T[0], next_eip); + gen_push_v(s, cpu_T[0]); gen_jmp(s, tval); } break; @@ -6843,24 +6442,26 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (CODE64(s)) goto illegal_op; - ot = dflag ? OT_LONG : OT_WORD; + ot = dflag; offset = insn_get(env, s, ot); - selector = insn_get(env, s, OT_WORD); + selector = insn_get(env, s, MO_16); - gen_op_movl_T0_im(selector); - gen_op_movl_T1_imu(offset); + tcg_gen_movi_tl(cpu_T[0], selector); + tcg_gen_movi_tl(cpu_T[1], offset); } goto do_lcall; case 0xe9: /* jmp im */ - if (dflag) - tval = (int32_t)insn_get(env, s, OT_LONG); - else - tval = (int16_t)insn_get(env, s, OT_WORD); + if (dflag != MO_16) { + tval = (int32_t)insn_get(env, s, MO_32); + } else { + tval = (int16_t)insn_get(env, s, MO_16); + } tval += s->pc - s->cs_base; - if (s->dflag == 0) + if (dflag == MO_16) { tval &= 0xffff; - else if(!CODE64(s)) + } else if (!CODE64(s)) { tval &= 0xffffffff; + } gen_jmp(s, tval); break; case 0xea: /* ljmp im */ @@ -6869,48 +6470,50 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (CODE64(s)) goto illegal_op; - ot = dflag ? OT_LONG : OT_WORD; + ot = dflag; offset = insn_get(env, s, ot); - selector = insn_get(env, s, OT_WORD); + selector = insn_get(env, s, MO_16); - gen_op_movl_T0_im(selector); - gen_op_movl_T1_imu(offset); + tcg_gen_movi_tl(cpu_T[0], selector); + tcg_gen_movi_tl(cpu_T[1], offset); } goto do_ljmp; case 0xeb: /* jmp Jb */ - tval = (int8_t)insn_get(env, s, OT_BYTE); + tval = (int8_t)insn_get(env, s, MO_8); tval += s->pc - s->cs_base; - if (s->dflag == 0) + if (dflag == MO_16) { tval &= 0xffff; + } gen_jmp(s, tval); break; case 0x70 ... 0x7f: /* jcc Jb */ - tval = (int8_t)insn_get(env, s, OT_BYTE); + tval = (int8_t)insn_get(env, s, MO_8); goto do_jcc; case 0x180 ... 0x18f: /* jcc Jv */ - if (dflag) { - tval = (int32_t)insn_get(env, s, OT_LONG); + if (dflag != MO_16) { + tval = (int32_t)insn_get(env, s, MO_32); } else { - tval = (int16_t)insn_get(env, s, OT_WORD); + tval = (int16_t)insn_get(env, s, MO_16); } do_jcc: next_eip = s->pc - s->cs_base; tval += next_eip; - if (s->dflag == 0) + if (dflag == MO_16) { tval &= 0xffff; + } gen_jcc(s, b, tval, next_eip); break; case 0x190 ... 0x19f: /* setcc Gv */ modrm = cpu_ldub_code(env, s->pc++); gen_setcc1(s, b, cpu_T[0]); - gen_ldst_modrm(env, s, modrm, OT_BYTE, OR_TMP0, 1); + gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1); break; case 0x140 ... 0x14f: /* cmov Gv, Ev */ if (!(s->cpuid_features & CPUID_CMOV)) { goto illegal_op; } - ot = dflag + OT_WORD; + ot = dflag; modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; gen_cmovcc1(env, s, ot, b, modrm, reg); @@ -6925,7 +6528,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } else { gen_update_cc_op(s); gen_helper_read_eflags(cpu_T[0], cpu_env); - gen_push_T0(s); + gen_push_v(s, cpu_T[0]); } break; case 0x9d: /* popf */ @@ -6933,9 +6536,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (s->vm86 && s->iopl != 3) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { - gen_pop_T0(s); + ot = gen_pop_T0(s); if (s->cpl == 0) { - if (s->dflag) { + if (dflag != MO_16) { gen_helper_write_eflags(cpu_env, cpu_T[0], tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | @@ -6950,7 +6553,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } } else { if (s->cpl <= s->iopl) { - if (s->dflag) { + if (dflag != MO_16) { gen_helper_write_eflags(cpu_env, cpu_T[0], tcg_const_i32((TF_MASK | AC_MASK | @@ -6967,7 +6570,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, & 0xffff)); } } else { - if (s->dflag) { + if (dflag != MO_16) { gen_helper_write_eflags(cpu_env, cpu_T[0], tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK))); @@ -6979,7 +6582,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } } } - gen_pop_update(s); + gen_pop_update(s, ot); set_cc_op(s, CC_OP_EFLAGS); /* abort translation because TF/AC flag may change */ gen_jmp_im(s->pc - s->cs_base); @@ -6989,7 +6592,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x9e: /* sahf */ if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) goto illegal_op; - gen_op_mov_TN_reg(OT_BYTE, 0, R_AH); + gen_op_mov_v_reg(MO_8, cpu_T[0], R_AH); gen_compute_eflags(s); tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O); tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C); @@ -7001,7 +6604,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_compute_eflags(s); /* Note: gen_compute_eflags() only gives the condition codes */ tcg_gen_ori_tl(cpu_T[0], cpu_cc_src, 0x02); - gen_op_mov_reg_T0(OT_BYTE, R_AH); + gen_op_mov_reg_v(MO_8, R_AH, cpu_T[0]); break; case 0xf5: /* cmc */ gen_compute_eflags(s); @@ -7027,21 +6630,21 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, /************************/ /* bit operations */ case 0x1ba: /* bt/bts/btr/btc Gv, im */ - ot = dflag + OT_WORD; + ot = dflag; modrm = cpu_ldub_code(env, s->pc++); op = (modrm >> 3) & 7; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); if (mod != 3) { s->rip_offset = 1; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_ld_T0_A0(ot + s->mem_index); + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_TN_reg(ot, 0, rm); + gen_op_mov_v_reg(ot, cpu_T[0], rm); } /* load shift */ val = cpu_ldub_code(env, s->pc++); - gen_op_movl_T1_im(val); + tcg_gen_movi_tl(cpu_T[1], val); if (op < 4) goto illegal_op; op -= 4; @@ -7058,22 +6661,22 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x1bb: /* btc */ op = 3; do_btx: - ot = dflag + OT_WORD; + ot = dflag; modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); - gen_op_mov_TN_reg(OT_LONG, 1, reg); + gen_op_mov_v_reg(MO_32, cpu_T[1], reg); if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); /* specific case: we need to add a displacement */ gen_exts(ot, cpu_T[1]); tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot); tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot); tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); - gen_op_ld_T0_A0(ot + s->mem_index); + gen_op_ld_v(s, ot, cpu_T[0], cpu_A0); } else { - gen_op_mov_TN_reg(ot, 0, rm); + gen_op_mov_v_reg(ot, cpu_T[0], rm); } bt_op: tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1); @@ -7105,17 +6708,18 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } set_cc_op(s, CC_OP_SARB + ot); if (op != 0) { - if (mod != 3) - gen_op_st_T0_A0(ot + s->mem_index); - else - gen_op_mov_reg_T0(ot, rm); + if (mod != 3) { + gen_op_st_v(s, ot, cpu_T[0], cpu_A0); + } else { + gen_op_mov_reg_v(ot, rm, cpu_T[0]); + } tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4); tcg_gen_movi_tl(cpu_cc_dst, 0); } break; case 0x1bc: /* bsf / tzcnt */ case 0x1bd: /* bsr / lzcnt */ - ot = dflag + OT_WORD; + ot = dflag; modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); @@ -7164,7 +6768,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, tcg_gen_movcond_tl(TCG_COND_EQ, cpu_T[0], cpu_cc_dst, cpu_tmp0, cpu_regs[reg], cpu_T[0]); } - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); break; /************************/ /* bcd */ @@ -7314,17 +6918,17 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x62: /* bound */ if (CODE64(s)) goto illegal_op; - ot = dflag ? OT_LONG : OT_WORD; + ot = dflag; modrm = cpu_ldub_code(env, s->pc++); reg = (modrm >> 3) & 7; mod = (modrm >> 6) & 3; if (mod == 3) goto illegal_op; - gen_op_mov_TN_reg(ot, 0, reg); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_op_mov_v_reg(ot, cpu_T[0], reg); + gen_lea_modrm(env, s, modrm); gen_jmp_im(pc_start - s->cs_base); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); - if (ot == OT_WORD) { + if (ot == MO_16) { gen_helper_boundw(cpu_env, cpu_A0, cpu_tmp2_i32); } else { gen_helper_boundl(cpu_env, cpu_A0, cpu_tmp2_i32); @@ -7333,17 +6937,17 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x1c8 ... 0x1cf: /* bswap reg */ reg = (b & 7) | REX_B(s); #ifdef TARGET_X86_64 - if (dflag == 2) { - gen_op_mov_TN_reg(OT_QUAD, 0, reg); + if (dflag == MO_64) { + gen_op_mov_v_reg(MO_64, cpu_T[0], reg); tcg_gen_bswap64_i64(cpu_T[0], cpu_T[0]); - gen_op_mov_reg_T0(OT_QUAD, reg); + gen_op_mov_reg_v(MO_64, reg, cpu_T[0]); } else #endif { - gen_op_mov_TN_reg(OT_LONG, 0, reg); + gen_op_mov_v_reg(MO_32, cpu_T[0], reg); tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); tcg_gen_bswap32_tl(cpu_T[0], cpu_T[0]); - gen_op_mov_reg_T0(OT_LONG, reg); + gen_op_mov_reg_v(MO_32, reg, cpu_T[0]); } break; case 0xd6: /* salc */ @@ -7351,7 +6955,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; gen_compute_eflags_c(s, cpu_T[0]); tcg_gen_neg_tl(cpu_T[0], cpu_T[0]); - gen_op_mov_reg_T0(OT_BYTE, R_EAX); + gen_op_mov_reg_v(MO_8, R_EAX, cpu_T[0]); break; case 0xe0: /* loopnz */ case 0xe1: /* loopz */ @@ -7360,11 +6964,12 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, { int l1, l2, l3; - tval = (int8_t)insn_get(env, s, OT_BYTE); + tval = (int8_t)insn_get(env, s, MO_8); next_eip = s->pc - s->cs_base; tval += next_eip; - if (s->dflag == 0) + if (dflag == MO_16) { tval &= 0xffff; + } l1 = gen_new_label(); l2 = gen_new_label(); @@ -7449,7 +7054,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } else { gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_sysexit(cpu_env, tcg_const_i32(dflag)); + gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1)); gen_eob(s); } break; @@ -7467,7 +7072,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } else { gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_sysret(cpu_env, tcg_const_i32(s->dflag)); + gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1)); /* condition codes are modified only in long mode */ if (s->lma) { set_cc_op(s, CC_OP_EFLAGS); @@ -7501,9 +7106,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ); tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,ldt.selector)); - ot = OT_WORD; - if (mod == 3) - ot += s->dflag; + ot = mod == 3 ? dflag : MO_16; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); break; case 2: /* lldt */ @@ -7513,7 +7116,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE); - gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); gen_jmp_im(pc_start - s->cs_base); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_lldt(cpu_env, cpu_tmp2_i32); @@ -7524,9 +7127,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ); tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,tr.selector)); - ot = OT_WORD; - if (mod == 3) - ot += s->dflag; + ot = mod == 3 ? dflag : MO_16; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1); break; case 3: /* ltr */ @@ -7536,7 +7137,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE); - gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); gen_jmp_im(pc_start - s->cs_base); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_ltr(cpu_env, cpu_tmp2_i32); @@ -7546,7 +7147,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 5: /* verw */ if (!s->pe || s->vm86) goto illegal_op; - gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); gen_update_cc_op(s); if (op == 4) { gen_helper_verr(cpu_env, cpu_T[0]); @@ -7569,14 +7170,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (mod == 3) goto illegal_op; gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.limit)); - gen_op_st_T0_A0(OT_WORD + s->mem_index); + gen_op_st_v(s, MO_16, cpu_T[0], cpu_A0); gen_add_A0_im(s, 2); tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, gdt.base)); - if (!s->dflag) - gen_op_andl_T0_im(0xffffff); - gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index); + if (dflag == MO_16) { + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff); + } + gen_op_st_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0); break; case 1: if (mod == 3) { @@ -7587,16 +7189,8 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, goto illegal_op; gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); -#ifdef TARGET_X86_64 - if (s->aflag == 2) { - gen_op_movq_A0_reg(R_EAX); - } else -#endif - { - gen_op_movl_A0_reg(R_EAX); - if (s->aflag == 0) - gen_op_andl_A0_ffff(); - } + tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EAX]); + gen_extu(s->aflag, cpu_A0); gen_add_A0_ds_seg(s); gen_helper_monitor(cpu_env, cpu_A0); break; @@ -7632,14 +7226,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } } else { /* sidt */ gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.limit)); - gen_op_st_T0_A0(OT_WORD + s->mem_index); + gen_op_st_v(s, MO_16, cpu_T[0], cpu_A0); gen_add_A0_im(s, 2); tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, idt.base)); - if (!s->dflag) - gen_op_andl_T0_im(0xffffff); - gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index); + if (dflag == MO_16) { + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff); + } + gen_op_st_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0); } break; case 2: /* lgdt */ @@ -7655,7 +7250,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); break; } else { - gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag), + gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1), tcg_const_i32(s->pc - pc_start)); tcg_gen_exit_tb(0); s->is_jmp = DISAS_TB_JUMP; @@ -7673,7 +7268,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); break; } else { - gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag)); + gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1)); } break; case 3: /* VMSAVE */ @@ -7683,7 +7278,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); break; } else { - gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag)); + gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1)); } break; case 4: /* STGI */ @@ -7722,7 +7317,8 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); break; } else { - gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag)); + gen_helper_invlpga(cpu_env, + tcg_const_i32(s->aflag - 1)); } break; default: @@ -7733,12 +7329,13 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } else { gen_svm_check_intercept(s, pc_start, op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_ld_T1_A0(OT_WORD + s->mem_index); + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, MO_16, cpu_T[1], cpu_A0); gen_add_A0_im(s, 2); - gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index); - if (!s->dflag) - gen_op_andl_T0_im(0xffffff); + gen_op_ld_v(s, CODE64(s) + MO_32, cpu_T[0], cpu_A0); + if (dflag == MO_16) { + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffff); + } if (op == 2) { tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,gdt.base)); tcg_gen_st32_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,gdt.limit)); @@ -7755,14 +7352,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, #else tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,cr[0])); #endif - gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 1); + gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 1); break; case 6: /* lmsw */ if (s->cpl != 0) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0); - gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); gen_helper_lmsw(cpu_env, cpu_T[0]); gen_jmp_im(s->pc - s->cs_base); gen_eob(s); @@ -7775,7 +7372,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, } else { gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); gen_helper_invlpg(cpu_env, cpu_A0); gen_jmp_im(s->pc - s->cs_base); gen_eob(s); @@ -7839,7 +7436,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (CODE64(s)) { int d_ot; /* d_ot is the size of destination */ - d_ot = dflag + OT_WORD; + d_ot = dflag; modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; @@ -7847,19 +7444,16 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, rm = (modrm & 7) | REX_B(s); if (mod == 3) { - gen_op_mov_TN_reg(OT_LONG, 0, rm); + gen_op_mov_v_reg(MO_32, cpu_T[0], rm); /* sign extend */ - if (d_ot == OT_QUAD) + if (d_ot == MO_64) { tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - gen_op_mov_reg_T0(d_ot, reg); - } else { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - if (d_ot == OT_QUAD) { - gen_op_lds_T0_A0(OT_LONG + s->mem_index); - } else { - gen_op_ld_T0_A0(OT_LONG + s->mem_index); } - gen_op_mov_reg_T0(d_ot, reg); + gen_op_mov_reg_v(d_ot, reg, cpu_T[0]); + } else { + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, MO_32 | MO_SIGN, cpu_T[0], cpu_A0); + gen_op_mov_reg_v(d_ot, reg, cpu_T[0]); } } else #endif @@ -7872,14 +7466,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, t0 = tcg_temp_local_new(); t1 = tcg_temp_local_new(); t2 = tcg_temp_local_new(); - ot = OT_WORD; + ot = MO_16; modrm = cpu_ldub_code(env, s->pc++); reg = (modrm >> 3) & 7; mod = (modrm >> 6) & 3; rm = modrm & 7; if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_ld_v(ot + s->mem_index, t0, cpu_A0); + gen_lea_modrm(env, s, modrm); + gen_op_ld_v(s, ot, t0, cpu_A0); a0 = tcg_temp_local_new(); tcg_gen_mov_tl(a0, cpu_A0); } else { @@ -7897,7 +7491,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, tcg_gen_movi_tl(t2, CC_Z); gen_set_label(label1); if (mod != 3) { - gen_op_st_v(ot + s->mem_index, t0, a0); + gen_op_st_v(s, ot, t0, a0); tcg_temp_free(a0); } else { gen_op_mov_reg_v(ot, rm, t0); @@ -7917,10 +7511,10 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, TCGv t0; if (!s->pe || s->vm86) goto illegal_op; - ot = dflag ? OT_LONG : OT_WORD; + ot = dflag != MO_16 ? MO_32 : MO_16; modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; - gen_ldst_modrm(env, s, modrm, OT_WORD, OR_TMP0, 0); + gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); t0 = tcg_temp_local_new(); gen_update_cc_op(s); if (b == 0x102) { @@ -7948,7 +7542,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 3: /* prefetchnt0 */ if (mod == 3) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); /* nothing more to do */ break; default: /* nop (multi byte) */ @@ -7974,9 +7568,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) - ot = OT_QUAD; + ot = MO_64; else - ot = OT_LONG; + ot = MO_32; if ((prefixes & PREFIX_LOCK) && (reg == 0) && (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) { reg = 8; @@ -7990,14 +7584,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); if (b & 2) { - gen_op_mov_TN_reg(ot, 0, rm); + gen_op_mov_v_reg(ot, cpu_T[0], rm); gen_helper_write_crN(cpu_env, tcg_const_i32(reg), cpu_T[0]); gen_jmp_im(s->pc - s->cs_base); gen_eob(s); } else { gen_helper_read_crN(cpu_T[0], cpu_env, tcg_const_i32(reg)); - gen_op_mov_reg_T0(ot, rm); + gen_op_mov_reg_v(ot, rm, cpu_T[0]); } break; default: @@ -8019,22 +7613,22 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) - ot = OT_QUAD; + ot = MO_64; else - ot = OT_LONG; + ot = MO_32; /* XXX: do it dynamically with CR4.DE bit */ if (reg == 4 || reg == 5 || reg >= 8) goto illegal_op; if (b & 2) { gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg); - gen_op_mov_TN_reg(ot, 0, rm); + gen_op_mov_v_reg(ot, cpu_T[0], rm); gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]); gen_jmp_im(s->pc - s->cs_base); gen_eob(s); } else { gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg); tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg])); - gen_op_mov_reg_T0(ot, rm); + gen_op_mov_reg_v(ot, rm, cpu_T[0]); } } break; @@ -8053,7 +7647,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, case 0x1c3: /* MOVNTI reg, mem */ if (!(s->cpuid_features & CPUID_SSE2)) goto illegal_op; - ot = s->dflag == 2 ? OT_QUAD : OT_LONG; + ot = mo_64_32(dflag); modrm = cpu_ldub_code(env, s->pc++); mod = (modrm >> 6) & 3; if (mod == 3) @@ -8075,10 +7669,10 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); break; } - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32((s->dflag == 2))); + gen_helper_fxsave(cpu_env, cpu_A0, tcg_const_i32(dflag == MO_64)); break; case 1: /* fxrstor */ if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || @@ -8088,11 +7682,10 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); break; } - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); gen_update_cc_op(s); gen_jmp_im(pc_start - s->cs_base); - gen_helper_fxrstor(cpu_env, cpu_A0, - tcg_const_i32((s->dflag == 2))); + gen_helper_fxrstor(cpu_env, cpu_A0, tcg_const_i32(dflag == MO_64)); break; case 2: /* ldmxcsr */ case 3: /* stmxcsr */ @@ -8103,14 +7696,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) || mod == 3) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); if (op == 2) { - gen_op_ld_T0_A0(OT_LONG + s->mem_index); - tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); + tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, + s->mem_index, MO_LEUL); gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32); } else { tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr)); - gen_op_st_T0_A0(OT_LONG + s->mem_index); + gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0); } break; case 5: /* lfence */ @@ -8128,7 +7721,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, /* clflush */ if (!(s->cpuid_features & CPUID_CLFLUSH)) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); } break; default: @@ -8140,7 +7733,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, mod = (modrm >> 6) & 3; if (mod == 3) goto illegal_op; - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_lea_modrm(env, s, modrm); /* ignore for now */ break; case 0x1aa: /* rsm */ @@ -8162,16 +7755,15 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; - if (s->prefix & PREFIX_DATA) - ot = OT_WORD; - else if (s->dflag != 2) - ot = OT_LONG; - else - ot = OT_QUAD; + if (s->prefix & PREFIX_DATA) { + ot = MO_16; + } else { + ot = mo_64_32(dflag); + } gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_helper_popcnt(cpu_T[0], cpu_env, cpu_T[0], tcg_const_i32(ot)); - gen_op_mov_reg_T0(ot, reg); + gen_op_mov_reg_v(ot, reg, cpu_T[0]); set_cc_op(s, CC_OP_EFLAGS); break; @@ -8205,6 +7797,37 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, void optimize_flags_init(void) { + static const char reg_names[CPU_NB_REGS][4] = { +#ifdef TARGET_X86_64 + [R_EAX] = "rax", + [R_EBX] = "rbx", + [R_ECX] = "rcx", + [R_EDX] = "rdx", + [R_ESI] = "rsi", + [R_EDI] = "rdi", + [R_EBP] = "rbp", + [R_ESP] = "rsp", + [8] = "r8", + [9] = "r9", + [10] = "r10", + [11] = "r11", + [12] = "r12", + [13] = "r13", + [14] = "r14", + [15] = "r15", +#else + [R_EAX] = "eax", + [R_EBX] = "ebx", + [R_ECX] = "ecx", + [R_EDX] = "edx", + [R_ESI] = "esi", + [R_EDI] = "edi", + [R_EBP] = "ebp", + [R_ESP] = "esp", +#endif + }; + int i; + cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUX86State, cc_op), "cc_op"); @@ -8215,57 +7838,11 @@ void optimize_flags_init(void) cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src2), "cc_src2"); -#ifdef TARGET_X86_64 - cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[R_EAX]), "rax"); - cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[R_ECX]), "rcx"); - cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[R_EDX]), "rdx"); - cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[R_EBX]), "rbx"); - cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[R_ESP]), "rsp"); - cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[R_EBP]), "rbp"); - cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[R_ESI]), "rsi"); - cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[R_EDI]), "rdi"); - cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[8]), "r8"); - cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[9]), "r9"); - cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[10]), "r10"); - cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[11]), "r11"); - cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[12]), "r12"); - cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[13]), "r13"); - cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[14]), "r14"); - cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUX86State, regs[15]), "r15"); -#else - cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUX86State, regs[R_EAX]), "eax"); - cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUX86State, regs[R_ECX]), "ecx"); - cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUX86State, regs[R_EDX]), "edx"); - cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUX86State, regs[R_EBX]), "ebx"); - cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUX86State, regs[R_ESP]), "esp"); - cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUX86State, regs[R_EBP]), "ebp"); - cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUX86State, regs[R_ESI]), "esi"); - cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUX86State, regs[R_EDI]), "edi"); -#endif + for (i = 0; i < CPU_NB_REGS; ++i) { + cpu_regs[i] = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUX86State, regs[i]), + reg_names[i]); + } } /* generate intermediate code in gen_opc_buf and gen_opparam_buf for @@ -8311,7 +7888,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu, /* select memory access functions */ dc->mem_index = 0; if (flags & HF_SOFTMMU_MASK) { - dc->mem_index = (cpu_mmu_index(env) + 1) << 2; + dc->mem_index = cpu_mmu_index(env); } dc->cpuid_features = env->features[FEAT_1_EDX]; dc->cpuid_ext_features = env->features[FEAT_1_ECX]; diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index 91c60ebaae..b381477d29 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -112,7 +112,7 @@ void openrisc_translate_init(void) } } -/* Writeback SR_F transaltion-space to execution-space. */ +/* Writeback SR_F translation space to execution space. */ static inline void wb_SR_F(void) { int label; diff --git a/tests/Makefile b/tests/Makefile index 8d258781b7..0b85a34147 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -52,6 +52,8 @@ check-unit-y += tests/test-int128$(EXESUF) gcov-files-test-int128-y = check-unit-y += tests/test-bitops$(EXESUF) check-unit-y += tests/test-qdev-global-props$(EXESUF) +check-unit-y += tests/check-qom-interface$(EXESUF) +gcov-files-check-qom-interface-y = qom/object.c check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh @@ -138,6 +140,7 @@ test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o $(test-obj-y): QEMU_INCLUDES += -Itests QEMU_CFLAGS += -I$(SRC_PATH)/tests +qom-core-obj = qom/object.o qom/qom-qobject.o qom/container.o tests/test-x86-cpuid.o: QEMU_INCLUDES += -I$(SRC_PATH)/target-i386 @@ -147,6 +150,7 @@ tests/check-qdict$(EXESUF): tests/check-qdict.o libqemuutil.a tests/check-qlist$(EXESUF): tests/check-qlist.o libqemuutil.a tests/check-qfloat$(EXESUF): tests/check-qfloat.o libqemuutil.a tests/check-qjson$(EXESUF): tests/check-qjson.o libqemuutil.a libqemustub.a +tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(qom-core-obj) libqemuutil.a tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-throttle$(EXESUF): tests/test-throttle.o $(block-obj-y) libqemuutil.a libqemustub.a @@ -160,7 +164,7 @@ tests/test-int128$(EXESUF): tests/test-int128.o tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ hw/core/qdev.o hw/core/qdev-properties.o \ hw/core/irq.o \ - qom/object.o qom/container.o qom/qom-qobject.o \ + $(qom-core-obj) \ $(test-qapi-obj-y) \ libqemuutil.a libqemustub.a diff --git a/tests/acpi-test.c b/tests/acpi-test.c index ca83b1d6b6..df1af83158 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -382,6 +382,7 @@ int main(int argc, char *argv[]) { const char *arch = qtest_get_arch(); FILE *f = fopen(disk, "w"); + int ret; fwrite(boot_sector, 1, sizeof boot_sector, f); fclose(f); @@ -390,5 +391,7 @@ int main(int argc, char *argv[]) if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { qtest_add_func("acpi/tcg", test_acpi_tcg); } - return g_test_run(); + ret = g_test_run(); + unlink(disk); + return ret; } diff --git a/tests/check-qom-interface.c b/tests/check-qom-interface.c new file mode 100644 index 0000000000..f06380ef14 --- /dev/null +++ b/tests/check-qom-interface.c @@ -0,0 +1,105 @@ +/* + * QOM interface test. + * + * Copyright (C) 2013 Red Hat Inc. + * + * Authors: + * Igor Mammedov <imammedo@redhat.com> + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + */ +#include <glib.h> + +#include "qom/object.h" +#include "qemu/module.h" + + +#define TYPE_TEST_IF "test-interface" +#define TEST_IF_CLASS(klass) \ + OBJECT_CLASS_CHECK(TestIfClass, (klass), TYPE_TEST_IF) +#define TEST_IF_GET_CLASS(obj) \ + OBJECT_GET_CLASS(TestIfClass, (obj), TYPE_TEST_IF) +#define TEST_IF(obj) \ + INTERFACE_CHECK(TestIf, (obj), TYPE_TEST_IF) + +typedef struct TestIf { + Object parent_obj; +} TestIf; + +typedef struct TestIfClass { + InterfaceClass parent_class; + + uint32_t test; +} TestIfClass; + +static const TypeInfo test_if_info = { + .name = TYPE_TEST_IF, + .parent = TYPE_INTERFACE, + .class_size = sizeof(TestIfClass), +}; + +#define PATTERN 0xFAFBFCFD + +static void test_class_init(ObjectClass *oc, void *data) +{ + TestIfClass *tc = TEST_IF_CLASS(oc); + + g_assert(tc); + tc->test = PATTERN; +} + +#define TYPE_DIRECT_IMPL "direct-impl" + +static const TypeInfo direct_impl_info = { + .name = TYPE_DIRECT_IMPL, + .parent = TYPE_OBJECT, + .class_init = test_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_TEST_IF }, + { } + } +}; + +#define TYPE_INTERMEDIATE_IMPL "intermediate-impl" + +static const TypeInfo intermediate_impl_info = { + .name = TYPE_INTERMEDIATE_IMPL, + .parent = TYPE_DIRECT_IMPL, +}; + +static void test_interface_impl(const char *type) +{ + Object *obj = object_new(type); + TestIf *iobj = TEST_IF(obj); + TestIfClass *ioc = TEST_IF_GET_CLASS(iobj); + + g_assert(iobj); + g_assert(ioc->test == PATTERN); +} + +static void interface_direct_test(void) +{ + test_interface_impl(TYPE_DIRECT_IMPL); +} + +static void interface_intermediate_test(void) +{ + test_interface_impl(TYPE_INTERMEDIATE_IMPL); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + module_call_init(MODULE_INIT_QOM); + type_register_static(&test_if_info); + type_register_static(&direct_impl_info); + type_register_static(&intermediate_impl_info); + + g_test_add_func("/qom/interface/direct_impl", interface_direct_test); + g_test_add_func("/qom/interface/intermediate_impl", + interface_intermediate_test); + + return g_test_run(); +} diff --git a/ui/cocoa.m b/ui/cocoa.m index be491794dc..2524f185bc 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -240,9 +240,8 @@ int keymap[] = static int cocoa_keycode_to_qemu(int keycode) { - if((sizeof(keymap)/sizeof(int)) <= keycode) - { - printf("(cocoa) warning unknow keycode 0x%x\n", keycode); + if (ARRAY_SIZE(keymap) <= keycode) { + printf("(cocoa) warning unknown keycode 0x%x\n", keycode); return 0; } return keymap[keycode]; @@ -230,7 +230,7 @@ int ctrl_grab = 0; unsigned int nb_prom_envs = 0; const char *prom_envs[MAX_PROM_ENVS]; int boot_menu; -bool boot_strict; +static bool boot_strict; uint8_t *boot_splash_filedata; size_t boot_splash_filedata_size; uint8_t qemu_extra_params_fw[2]; @@ -461,7 +461,7 @@ static QemuOptsList qemu_boot_opts = { .type = QEMU_OPT_STRING, }, { .name = "strict", - .type = QEMU_OPT_STRING, + .type = QEMU_OPT_BOOL, }, { /*End of list */ } }, @@ -4081,6 +4081,7 @@ int main(int argc, char **argv, char **envp) } boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu); + boot_strict = qemu_opt_get_bool(opts, "strict", false); } if (!kernel_cmdline) { |